游戏弹幕系统实现

现在的公司在做一个VR影院的项目,需要实现弹幕聊天功能。在借鉴其它博主的实现思路上,做了一些改编,希望能为大家提供参考。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using DG.Tweening;
using System.Collections.Generic;
using System;
using TMPro;
/*
 * Author:W
 * 弹幕系统
 */
public class BulletMsgShowPanel : MonoBehaviour
{
    /// <summary>
    /// 弹幕信息父对象
    /// </summary>
    public Transform BulletMsgParent;

    /// <summary>
    /// 弹幕预设
    /// </summary>
    public GameObject BulletMsgPrefab;

    /// <summary>
    /// 弹幕物体的队列
    /// </summary>
    private Queue BulletMsgQueue = new Queue();

    /// <summary>
    /// 生成弹幕的时间间隔
    /// </summary>
    [SerializeField]
    [Tooltip("弹幕生成的时间间隔")]
    private float Timer;

    [SerializeField]
    [Tooltip("弹幕的在屏幕上的行数以及对应的Y坐标值")]
    private int[] RowArr = new int[] {560, 500, 440, 380 };//四行弹幕的位置

    private int Row_PosY;

    [SerializeField]
    [Tooltip("弹幕的生成位置的X坐标")]
    private float PosX_Max = 1200;
    [SerializeField]
    [Tooltip("弹幕运动目标位置的X坐标")]
    private float PosX_Min = -1300;

    /// <summary>
    /// 弹幕移动的时长
    /// </summary>
    [SerializeField]
    [Tooltip("弹幕运动时长")]
    private float BulletMsgMoveTime = 20;
    
    private Vector3 BulletMsgRefPositon;//生成弹幕位置
    private Quaternion BulletMsgRefRotation;//生产弹幕角度

    void Start()
    {
        RowArr = new int[] { 560, 500, 440, 380 };

        Row_PosY = RowArr[0];//默认弹幕生产在第一行
        BulletMsgRefPositon = new Vector3(PosX_Max, Row_PosY, 0);
        BulletMsgRefRotation.eulerAngles = new Vector3(0,0, 0);

        Timer = 2f;
    }

    void Update()
    {
        Timer -= Time.deltaTime;

        if (Timer <= 0f)
        {
            int i = UnityEngine.Random.Range(0, DanMuStrings.Length);//弹幕的随机内容
            
            //调用生成弹幕方法
            CreateBulletMsgObj(DanMuStrings[i]);

            Timer = 2f;//每隔2秒生成一个弹幕

        }

        #region    判断应该在第几行

        ComputeNewBulletMsgObjPos();

        #endregion

        //检查移出屏幕的弹幕,销毁处理
        if (BulletMsgQueue.Count > 0)//退出队列方法一(节省资源开销)
        {
            GameObject go = (GameObject)BulletMsgQueue.Peek();

            if (go.transform.localPosition.x <= PosX_Min)//当弹幕位置移出屏幕
            {
                BulletMsgQueue.Dequeue();//移出队列
                Destroy(go);//销毁弹幕
                //Debug.Log("save===" + BulletMsgQueue.Count);
            }

        }       
    }

    /// <summary>
    /// 计算下1条生成的弹幕能在那一行生成
    /// </summary>
    private void ComputeNewBulletMsgObjPos()
    {
        int index = 0;

        foreach (GameObject tex in BulletMsgQueue.ToArray())
        {
            for (int i = 0; i < RowArr.Length; i++)
            {
                if (tex.transform.localPosition.y == RowArr[i])
                {
                    if (i < RowArr.Length - 1)
                    {
                        index = i + 1;
                    }
                    else
                    {
                        index = 0; 
                    }
                }
            }           
        }

        Row_PosY = RowArr[index];
    }


    #region 弹幕内容(测试用)

    public string[] DanMuStrings =
    {

     "<sprite=0>这个剧情也太雷人了吧!<sprite=0>",

     "还是好莱坞的电影经典啊,<sprite=0>这个太次了还是好莱坞的电影经典啊",

     "是电锯惊魂的主角,尼玛<sprite=0>",

     "这个游戏还是很良心的么<sprite=0>",

     "卧槽还要花钱,这一关也太难卧槽还要花钱,这一关也太难了卧<sprite=0>",

     "这个游戏好棒偶<sprite=0>",

     "全是傻逼<sprite=0>",

     "求约:13122785566<sprite=0>",

     "最近好寂寞啊,还是这个游戏好啊是胸再大点<sprite=0>",

     "难道玩游戏还能撸<sprite=0>",

     "办证:010- 888888<sprite=0>",

     "为什么女主角没有死?<sprite=0>",

     "好帅呦,你这个娘们儿<sprite=0>",

     "欠揍啊,东北人不知道啊<sprite=0>",

     "我去都是什么人啊,请文明用语还是好莱坞的电影经典啊,<sprite=0>",

     "这个还是不错的<sprite=0>",

     "要是胸再大点就更好了<sprite=0>",

     "这个游戏必须顶啊<sprite=0>",

     "还是好莱坞的电影经典啊,这个太次了还是好莱坞的电影经典啊 <sprite=0>",

     "好吧,这也是醉了!<sprite=0>",

     "他只想做一个安静的美男子!<sprite=0>"
};

    #endregion

    /// <summary>
    /// 生成弹幕和移动弹幕
    /// </summary>
    public void CreateBulletMsgObj(string content)
    {
        GameObject bulletMsgObj;
        bulletMsgObj = (GameObject)(Instantiate(BulletMsgPrefab, BulletMsgRefPositon, BulletMsgRefRotation));//生成弹幕
        bulletMsgObj.SetActive(true);

        if (bulletMsgObj != null)
        {
            bulletMsgObj.transform.SetParent(BulletMsgParent);//设置父物体
            
            bulletMsgObj.transform.localScale = new Vector3(1, 1, 1);
            
            bulletMsgObj.transform.localRotation = BulletMsgRefRotation;

            //Debug.Log("Row_PosY================"+ Row_PosY);

            bulletMsgObj.transform.localPosition = new Vector3(PosX_Max, Row_PosY, 0);//--弹幕移动的起始位置X

            bulletMsgObj.transform.GetComponentInChildren<TextMeshProUGUI>().text = content;//弹幕内容 

            //移动弹幕(20秒移动到-1300的位置)
            bulletMsgObj.transform.DOLocalMoveX(PosX_Min, BulletMsgMoveTime);            
        }

        //生成的弹幕添加到队列
        BulletMsgQueue.Enqueue(bulletMsgObj);
    }
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Data菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值