您的位置:首页 > 移动开发 > Unity3D

Unity3D实现弹幕的效果

2015-06-18 09:08 519 查看
孙广东 2015.6.15



对于逗比的游戏、无厘头、可以让大家吐糟的游戏,如果有弹幕的功能是极好的。
使用U5和 UGUI 目前实现的很简陋而已。
/// <summary>
    /// 实现看视频时的弹幕效果
    /// </summary>
    public class DanMu : MonoBehaviour
    {
        //public Text[] texts;
        public GameObject textPrefab;

        [Tooltip("满屏的个数")] public int num;

        private Queue<GameObject> Texts = new Queue<GameObject>();
        private bool isDanmuOn = true;
        private IEnumerator coroutine;

        // Use this for initialization
        void Start()
        {
            for (int i = 0; i < num; i++)
            {
                GameObject obj = Instantiate(textPrefab, transform.position, Quaternion.identity) as GameObject;
                obj.SetActive(false);
                obj.transform.SetParent(transform);
                obj.transform.localScale = Vector3.one;
                Texts.Enqueue(obj);
            }
            coroutine = DanmuAnimation();
            StartCoroutine(coroutine);
        }

        private IEnumerator DanmuAnimation()       
        {
            while (true)
            {
                GameObject obj = Texts.Dequeue();
                if (obj)
                {
                    obj.transform.localPosition = new Vector3(1071, Random.Range(-512, 512));
                    obj.GetComponent<Text>().text = DanMuStrings[Random.Range(0, DanMuStrings.Length)];
                    obj.GetComponent<Text>().color = TextColors[Random.Range(0, TextColors.Length)];
                    obj.SetActive(true);

                    obj.GetComponent<DanMuText>().Reset(Texts);
                }

                yield return new WaitForSeconds(0.2f);                
            }
        }

        /// <summary>
        /// 弹幕的开关
        /// </summary>
        public void DanMuToggle(Toggle toggle)
        {
            if (toggle.isOn)
            {
                isDanmuOn = true;
                StartCoroutine(coroutine);
                MyDebugLog.Log("弹幕开!!!!!");
            }
            else
            {
                isDanmuOn = false;
                DOTween.KillAll();
                StopCoroutine(coroutine);
                // Texts.Clear();
                foreach (var text in transform.GetComponentsInChildren<DanMuText>())                  // 只能得到被激活的对象而已, 得不到全部?  所以不用Clear()直接把这些在外面的入队就行
                {
                    Texts.Enqueue(text.gameObject);
                    text.gameObject.SetActive(false);
                }
                MyDebugLog.Log("弹幕关!!!!!个数: " + Texts.Count);
            }
        }

        [HideInInspector]
        public string[] DanMuStrings =
        {
            "这个剧情也太雷人了吧!",
            "还是好莱坞的电影经典啊,这个太次了",
            "是电锯惊魂的主角,尼玛",
            "这个游戏还是很良心的么",
            "卧槽还要花钱,这一关也太难了",
            "这个游戏好棒偶",
            "全是傻逼",
            "求约:13122785566",
            "最近好寂寞啊,还是这个游戏好啊",
            "难道玩游戏还能撸",
            "办证:010 - 888888",
            "为什么女主角没有死?",
            "好帅呦,你这个娘们儿",
            "欠揍啊,东北人不知道啊",
            "我去都是什么人啊,请文明用语",
            "这个还是不错的",
            "要是胸再大点就更好了",
            "这个游戏必须顶啊",
            "怎么没有日本动作爱情片中的角色呢?",
            "好吧,这也是醉了!",
            "他只想做一个安静的美男子!"
        };

        public Color[] TextColors;
    }


和挂在 Text预制体上的 脚本:
/// <summary>
    /// 
    /// </summary>
    public class DanMuText : MonoBehaviour
    {

        public void Reset(Queue<GameObject> Texts)
        {
            transform.DOLocalMoveX(-1366, 4f).OnComplete(() =>
            {
                gameObject.SetActive(false);
                Texts.Enqueue(gameObject);
            });
        }
    }


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: