欢迎来到淼淼之森的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注同名公众号:Java学习之道

unity实战之弹幕功能

  |   0 评论   |   0 浏览

前言

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

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


标题:unity实战之弹幕功能
作者:shirlnGame
地址:https://www.mmzsblog.cn/articles/2022/08/11/1660200521185.html

如未加特殊说明,文章均为原创,转载必须注明出处。均采用CC BY-SA 4.0 协议

本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。若本站转载文章遗漏了原文链接,请及时告知,我们将做删除处理!文章观点不代表本网站立场,如需处理请联系首页客服。
• 网站转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。
• 公众号转载请联系网站首页的微信号申请白名单!

个人微信公众号 ↓↓↓                 

微信搜一搜爱上游戏开发