unity弹幕功能实现

近年来直播app和视频app如日中天,在这些app里往往会有一个弹幕功能。实际的项目中肯定是用服务器客户端直接的数据来控制的,这里只在客户端进行测试实现弹幕核心功能。
下面说的就是我是如何实现弹幕功能的。

首先是需求:要求全屏有四行弹幕,从下至上排列,每行依次显示,弹幕从右往左移动。弹幕移动出屏幕就消失。
制作步骤:
1)建立弹幕文字的prefab和要显示的UI;(下图中DanmuText就是弹幕text的预设物体,parents是弹幕在UI中作为parents的子物体)
 

2)新建脚本productdanmu添加给Canvas,然后将弹幕预设和弹幕的父物体拖进去(如上图)。
重点是productdanmu脚本中弹幕移动的实现
下面是源码:
[C#]  纯文本查看  复制代码
?
 
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using DG.Tweening;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System;
 
public class productdanmu : MonoBehaviour
{
     public GameObject textsdanmu, Danmu_parents; //弹幕预设物体和其父物体
 
     private GameObject texts; //生成的弹幕物体
     private Queue<GameObject> texts_queue = new Queue<GameObject>(); //弹幕物体的队列 
     private float production_timer; //生成弹幕的时间间隔
 
     private int [] numb = new int [] { 39, 139, 239, 339 }; //四行弹幕的位置
     
     private int Row_index; //弹幕行数变化
     private int a; 弹幕行数变化中间变量(桥的作用)
 
     private Vector3 textpositon; //生成弹幕位置
     private Quaternion textrotation; //生产弹幕角度
     private string content; //弹幕文字内容
     
 
 
     void Start()
     {
         Row_index = numb[0]; //默认弹幕生产在第一行
         textpositon = new Vector3(96, Row_index, 0); //弹幕默认位置
         textrotation.eulerAngles = new Vector3(0, 0, 0);
         production_timer = 2f;
     }
         
 
     void Update()
     {
         production_timer-=Time.deltaTime;
 
         if (production_timer<=0f)
         {
             int i = UnityEngine.Random.Range(0, DanMuStrings.Length); //弹幕的随机内容
             content = DanMuStrings[i];
 
             createDanMuEntity();        //调用生成弹幕方法
            
             production_timer = 2f; //每隔2秒生成一个弹幕
         }
          
             #region 判断应该在第几行
             foreach (GameObject tex in texts_queue.ToArray()) //判断每一行是否满了
             {
                 if (tex.transform.localPosition.y == numb[0]) //第一行
                 {
              
                     a = 2;
                
                 }
                 else
                     if (tex.transform.localPosition.y == numb[1]) //第二行
                 {
                    
                         a = 3;
                 }
                 else
                     if (tex.transform.localPosition.y == numb[2]) //第三行
                 {
                         a = 4;
                 }
                 else
                     if (tex.transform.localPosition.y == numb[3]) //第4行
                 {
                    
                         a = 1;
                 }
 
             }
 
             switch (a)
             {
                 case 1:
                     Row_index = numb[0];
                     break ;
                 case 2:
                     Row_index = numb[1];
                     break ;
                 case 3:
                     Row_index = numb[2];
                     break ;
                 case 4:
                     Row_index = numb[3];
                     break ;
                 default :
                     Debug.Log( "没有满足任何一行" );
                     break ;
             }
         #endregion
 
         if (texts_queue.Count >0) //退出队列方法一(节省资源开销)
         {
             GameObject go = texts_queue.Peek();
 
             if (go.transform.localPosition.x < -999) //当弹幕位置移出屏幕
             {
 
                 texts_queue.Dequeue(); //移出队列
                 Destroy(go); //销毁弹幕
 
                 Debug.Log( "save===" + texts_queue.Count);
             }
         }
 
         //foreach (GameObject tex in texts_queue.ToArray())//退出队列方法二(耗费资源开销)
         //{
         //    if (tex.transform.localPosition.x < -999)//当弹幕位置移出屏幕
         //    {
 
         //        texts_queue.Dequeue();//移出队列
         //        Destroy(tex);//销毁弹幕
 
         //        Debug.Log("save===" + texts_queue.Count);              
         //    }
         //}
 
     }
 
     [HideInInspector]
 
     #region 弹幕内容(测试用)
     public string [] DanMuStrings =
     {
         "这个剧情也太雷人了吧!" ,
         "还是好莱坞的电影经典啊,这个太次了还是好莱坞的电影经典啊,这个太次了" ,
         "是电锯惊魂的主角,尼玛" ,
         "这个游戏还是很良心的么" ,
         "卧槽还要花钱,这一关也太难卧槽还要花钱,这一关也太难了卧槽还要花钱,这一关也太难了卧槽还要花钱,这一关也太难了了" ,
         "这个游戏好棒偶" ,
         "全是傻逼" ,
         "求约:13122785566" ,
         "最近好寂寞啊,还是这个游戏好啊是胸再大点就更是胸再大点就更是胸再大点就更" ,
         "难道玩游戏还能撸" ,
         "办证:010 - 888888" ,
         "为什么女主角没有死?" ,
         "好帅呦,你这个娘们儿" ,
         "欠揍啊,东北人不知道啊" ,
         "我去都是什么人啊,请文明用语还是好莱坞的电影经典啊,这个太次了是胸再大点就更" ,
         "这个还是不错的" ,
         "要是胸再大点就更好了" ,
         "这个游戏必须顶啊" ,
         "还是好莱坞的电影经典啊,这个太次了还是好莱坞的电影经典啊,这个太次了怎么没有日本动作爱情片中的角色呢?" ,
         "好吧,这也是醉了!" ,
         "他只想做一个安静的美男子!"
     };
     #endregion
     public void createDanMuEntity() //生成弹幕和移动弹幕
     {
         texts = (GameObject)(Instantiate(textsdanmu, textpositon, textrotation)); //生成弹幕
         if (texts != null )
         {
             texts.transform.SetParent(Danmu_parents.transform); //设置父物体
 
             // texts.transform.parent = Danmu_parents.transform;//设置父物体的另种方法
 
             texts.transform.localScale = new Vector3(1, 1, 1);
             textrotation.eulerAngles = new Vector3(0, 0, 0);
             texts.transform.localRotation = textrotation;
 
             texts.transform.localPosition = new Vector3(290, Row_index, 0); //--弹幕移动的起始位置X          
            
             texts.transform.GetComponent<Text>().text = content;    //弹幕内容              
             
 
             if (texts.GetComponent<DOTweenAnimation>() == null )
                 texts.AddComponent<DOTweenAnimation>(); //添加DOTween插件
             texts.transform.DOLocalMoveX(-1200, 20); //移动弹幕(20秒移动到-1200的位置)
         }
 
         texts_queue.Enqueue(texts); //生成的弹幕添加到队列
     }
     
 
}




代码中的注释已经讲解了弹幕功能制作的每一步。大致思路是:

每隔2秒创建一个弹幕,然后使用DOTWeen插件进行弹幕移动和位置控制;用队列对生成的弹幕先后顺序进行控制和销毁。


运行效果如下;


### 回答1: Unity弹幕文字图片是一种在游戏或者应用程序中实现的特效。它可以用来显示文字或者图片在屏幕上迅速移动,并且可以根据设定的规则进行排列和发射。 首先,Unity提供了丰富的文本功能,开发者可以通过在场景中添加Text组件来添加文字弹幕。可以设置文本内容、字体风格、颜色、大小等等。开发者可以根据自己的需求设置文字内容,如聊天信息、系统提示等等。然后,可以根据游戏逻辑或者用户的操作,利用Unity的动画系统来实现文字的移动效果。可以通过设置位置、旋转、缩放等属性来控制文字的运动轨迹,使其在屏幕上流畅地移动。 其次,Unity还提供了丰富的图片处理功能,可以在场景中添加Image组件来显示图片弹幕。开发者可以选择合适的图片资源,并设置位置、大小和颜色等属性来实现图片的显示效果。对于图片弹幕的移动效果,可以利用Unity的物理引擎或者自定义的脚本来控制图片的运动方式,使其在屏幕上按照一定的规则移动。 在实现弹幕文字图片效果时,还可以根据需要添加其他特效,比如阴影、发光等,来增强视觉效果。此外,开发者还可以根据游戏情节或者用户的操作,动态生成文字或者图片弹幕,使游戏或者应用更加丰富和有趣。 总的来说,Unity弹幕文字图片是利用Unity的文本和图片功能实现的一种特效。开发者可以通过设置属性和使用动画系统来控制文字和图片的显示和移动,从而创造出独特的弹幕效果。这种特效可以为游戏或者应用增加视觉上的吸引力,并且可以根据需要进行进一步的定制和扩展。 ### 回答2: Unity弹幕文字图片是指在Unity引擎中实现弹幕效果时,同时包含文字和图片的场景。弹幕是一种类似于滚动字幕的特效,常见于游戏、直播等场景中。在Unity中,可以通过使用粒子系统或者UI技术来实现弹幕文字图片效果。 首先,利用Unity的粒子系统,可以创建一个自定义的粒子效果,将文字和图片设为粒子的纹理,设置粒子的初始位置和速度,使其在场景中以一定的弹幕路径进行运动,并在一定时间后消失。这样,文字和图片就能以弹幕的形式呈现出来,营造出炫酷的视觉效果。 另外,可以利用Unity的UI技术来实现弹幕文字图片效果。通过创建UI元素,例如Text和Image,根据需要设置文字内容和图片资源。然后,给UI元素添加动画组件,设置动画的运动路径、速度和持续时间,使UI元素以弹幕的方式在屏幕上移动。同时,可以通过代码控制文字和图片的显示时间和位置,实现弹幕的效果。 无论是使用粒子系统还是UI技术,都需要考虑弹幕的运动轨迹、速度和展示时间等因素,以及与游戏或直播场景的交互。通过不断调整参数和优化效果,可以实现各种各样独特而丰富的弹幕文字图片效果。总之,Unity弹幕文字图片技术为游戏和直播等场景增添了更多的视觉和交互性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值