unity实战之弹幕功能

简介: 使用unity也可以实现追剧弹幕效果

前言

最近项目需要加一个弹幕的功能。天天追剧的我,对于弹幕这个东西简直不要太熟悉,但是突然让做一个这样一个功能,还是有点戳手不及。
先来欣赏一个视频网站上的弹幕吧,如下:

UI

创建按钮,命名为barrage_btn,用于控制弹幕的开关,下面有2张图片,分别命名为hideImg和showImg,用于显示弹幕开关的状态
创建发射弹幕按钮,命名为shoot_btn。
创建输入框input_barrage
创建弹幕移动载体(父类)barrageBg
1.png

代码

local ui = nil
local barrageProto = {
[1] = { word = "哈哈哈哈", },
[2] = { word = "小可爱来了", },
[3] = { word = "终于上线了", },
[4] = { word = "小木好逗啊", },
[5] = { word = "我永远喜欢做游戏", },
[6] = { word = "爱上游戏开发登场了", },
[7] = { word = "为Unity而来", },
}
local barragePool = {}
local barrageLineY = {-100, 0, 100, 150, 200, 250, 300}--从上到下每行弹幕位置
local myBarrage = {}

function herotalent:start()
    ui = {}
    ui.shootBtn = base:findobj("barrage_btn")
    utils.addclickevent(ui.shootBtn, base.ShootBarrage)
    ui.inputBarrage = base:findinput("input_barrage")
    ui.inputBarrage.characterLimit = 20--每条弹幕的字数限制
    ui.inputBarrageObj = base:findobj("bg")
    ui.barrage_btn = base:findobj("barrage_btn")
    utils.addclickevent(ui.barrage_btn, base.ClickCloseBarrageBtn)
    ui.closeBarrageObj = base:findobj("barrage_btn/hideImg")
    ui.showBarrageObj = base:findobj("barrage_btn/showImg")
    ui.barrageBgRect = base:findrect("barrageBg")
    ui.startPointObj = base:findobj("startPoint")
end

function herotalent:commit()
    ui.barrageBgRect.gameObject.transform:DOLocalMoveX(-8000, 68)
    base.RefreshUI()
end

function herotalent.RefreshUI()
    base.CreateBarragePool()
end

function base.ClickCloseBarrageBtn()
    SetActive(ui.closeBarrageObj, not ui.closeBarrageObj.activeInHierarchy)
    SetActive(ui.showBarrageObj, not ui.showBarrageObj.activeInHierarchy)
    SetActive(ui.inputBarrageObj, not ui.closeBarrageObj.activeInHierarchy)
    corStopBol = not ui.closeBarrageObj.activeInHierarchy
    if ui.closeBarrageObj.activeInHierarchy then 
        coroutine.resume(base.barCor)
    end
end

function base.ShootBarrage()
    if ui.inputBarrage.text ~= nil and ui.inputBarrage.text ~= "" then 
        if pb.isWarningInPutStr(ui.inputBarrage.text) then 
            printlog("弹幕内容包含违规字")
        else
            table.insert(myBarrage, ui.inputBarrage.text)
            base.ClickCloseBarrageBtn()
        end
        ui.inputBarrage.text = ""
    end
end

function base.CreateBarragePool()
    local randomseed = 10000 --随机种子
    math.randomseed(randomseed)
    local totalNum = table.tablelen(barrageProto)
    local time = 50
    local clearTime = 2
    local barrageGroup = {}
    base.barCor = coroutine.start(function()
        while time > 0 do 
            local waitTime = math.random(0, 1.0)
            while waitTime > 0 do
                waitTime = waitTime - 0.2
                time = time - 0.2
                clearTime = clearTime - 0.2
                coroutine.wait(0.2)
                if corStopBol then 
                    DOTween.Pause(ui.barrageBgRect.gameObject.transform)
                    coroutine.yield()
                    DOTween.Play(ui.barrageBgRect.gameObject.transform)
                end
            end
            local startPoint = ui.barrageBgRect.gameObject.transform:InverseTransformPoint(ui.startPointObj.transform.position)
            local index = 7
            local barText = nil
            local myBarrageBol = false
            if #myBarrage > 0 then 
                barText = myBarrage[1]
                for i = 6, 1, -1 do
                    if barragePool[i] then
                        local sizeX = barragePool[i]:GetComponent("RectTransform").sizeDelta.x / 2
                        if startPoint.x - barragePool[i].transform.localPosition.x > sizeX then 
                            index = i
                            break
                        end
                    else
                        index = i
                        break
                    end
                end
                myBarrageBol = true
            else
                local line = math.random(1, 6)
                barText = barrageProto[math.random(1, totalNum)].word
                if barragePool[line] then 
                    local sizeX = barragePool[line]:GetComponent("RectTransform").sizeDelta.x / 2
                    if startPoint.x - barragePool[line].transform.localPosition.x > sizeX then 
                        index = line
                    else
                        index = nil
                    end
                else
                    index = line
                end
            end
            if index then 
                local barObj = poolManager.AddObj("Modules/login/barrage.prefab", ui.barrageBgRect.gameObject)
                table.insert(barrageGroup, barObj)
                barObj:GetComponent("Text").text = barText
                UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(barObj:GetComponent("RectTransform"))
                barObj.transform.localPosition = Vector2.New(startPoint.x + barObj:GetComponent("RectTransform").sizeDelta.x / 2, barrageLineY[index])
                barragePool[index] = barObj
                if myBarrageBol then 
                    table.remove(myBarrage, 1)
                end
            end
            local clearIndex = {}
            if clearTime <= 0 then
                for k, v in ipairs(barrageGroup) do 
                    local tempX = v:GetComponent("RectTransform").sizeDelta.x * 2
                    if startPoint.x - v.transform.localPosition.x > tempX + 1440 then 
                        poolManager.RemoveObj("Modules/login/barrage.prefab", v)
                        table.insert(clearIndex, k)
                    end
                end
                if #clearIndex > 0 then 
                    for i = #clearIndex, 1, -1 do
                        table.remove(barrageGroup, clearIndex[i])
                    end
                end
                clearTime = 2
            end
        end
    end)
end

效果

运行效果如下:
6655546.gif

相关文章
|
20天前
|
数据可视化 搜索推荐 API
一款功能强大的Unity数据可视化图表库
今天大姚分享一款免费(基于MIT License协议)、开源、功能强大、简单易用、可配置的Unity数据可视化图表库:XCharts。
|
9月前
|
图形学
|
20天前
|
图形学
Unity Hololens2开发|(六)MRTK3子系统 DictationSubsystem(听写功能)
Unity Hololens2开发|(六)MRTK3子系统 DictationSubsystem(听写功能)
|
20天前
|
C# 图形学
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
61 0
|
20天前
|
vr&ar C# 图形学
【Unity 3D】VR飞机拆装后零件说明功能案例实战(附源码和演示视频 超详细)
【Unity 3D】VR飞机拆装后零件说明功能案例实战(附源码和演示视频 超详细)
47 0
|
20天前
|
vr&ar 图形学
【Unity 3D】VR飞机起飞喷火游戏案例实战(附源码和演示视频 超详细)
【Unity 3D】VR飞机起飞喷火游戏案例实战(附源码和演示视频 超详细)
71 0
|
20天前
|
图形学
【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)
【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)
219 0
|
20天前
|
C# 图形学
【Unity】2D游戏-愤怒的小鸟教学实战(附源码和实现步骤 超详细)
【Unity】2D游戏-愤怒的小鸟教学实战(附源码和实现步骤 超详细)
234 2
|
20天前
|
数据可视化 C# 图形学
【Unity 3D】图形界面GUI的讲解及在C#中实现用户登录界面的实战(附源码)
【Unity 3D】图形界面GUI的讲解及在C#中实现用户登录界面的实战(附源码)
84 0
|
10月前
|
图形学
【Unity实战系列】如何把你的二次元老婆/老公导入Unity进行二创并且进行二次元渲染?(附模型网站分享)
【Unity实战系列】如何把你的二次元老婆/老公导入Unity进行二创并且进行二次元渲染?(附模型网站分享)
387 0