DanmakuManager.cs
4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class DanmakuManager : MonoBehaviour
{
public RectTransform danmakuPanel; // 弹幕pannel
public GameObject danmakuPrefab;
public float speed = 100f; // px/sec
private int currentLine = 0;
public void AddDanmaku(string text,int direction)
{
if (direction == 1)
{
StartCoroutine(SpawnDanmakuHorizontal(text));
}
else
{
StartCoroutine(SpawnDanmakuVertical(text));
}
}
public void ClearDanmaku()
{
foreach (Transform child in danmakuPanel)
Destroy(child.gameObject);
}
//批量弹幕,每条弹幕添加延迟
//direction 1.横屏 2.竖屏
public void AddDanmakuBatch(List<string> texts, float delay,int direction)
{
StartCoroutine(SendDanmakusWithDelay(texts, delay, direction));
}
private IEnumerator SendDanmakusWithDelay(List<string> texts, float delay,int direction)
{
foreach (var text in texts)
{
AddDanmaku(text,direction); // 使用你已有的发送函数
yield return new WaitForSeconds(delay);
}
}
IEnumerator SpawnDanmakuVertical(string text)
{
// 实例化
GameObject obj = Instantiate(danmakuPrefab, danmakuPanel);
var tmp = obj.GetComponent<TextMeshProUGUI>();
tmp.text = text;
Color color;
if (ColorUtility.TryParseHtmlString("#F7C559", out color))
{
tmp.color = color;
}
// 获取 RectTransform
RectTransform rt = obj.GetComponent<RectTransform>();
// 获取弹幕面板高度与每行高度
float panelHeight = danmakuPanel.rect.height;
// 起始 Y 坐标(屏幕底部偏下)
float y = -panelHeight; // 起始点在面板下方
// X 保持水平居中(或你可以自定义)
float x = Random.Range(700f, 900f);
// 设置初始位置
rt.anchoredPosition = new Vector2(x, y);
// 移动到屏幕顶端
while (rt.anchoredPosition.y < panelHeight / 4)
{
rt.anchoredPosition += Vector2.up * speed * Time.deltaTime;
yield return null;
}
// 移除弹幕
Destroy(obj);
}
IEnumerator SpawnDanmakuHorizontal(string text)
{
// 实例化
GameObject obj = Instantiate(danmakuPrefab, danmakuPanel);
var tmp = obj.GetComponent<TextMeshProUGUI>();
tmp.text = text;
RectTransform rt = obj.GetComponent<RectTransform>();
float panelHeight = danmakuPanel.rect.height;
// 随机 Y 坐标(在整个 panel 高度范围内)
// 获取随机 Y 坐标,确保与上次相差至少 30
float randomY = GetRandomY(panelHeight, 30f);
rt.anchoredPosition = new Vector2(danmakuPanel.rect.width, randomY);
float width = tmp.preferredWidth;
// 向左移动直到超出屏幕
while (rt.anchoredPosition.x > -width)
{
rt.anchoredPosition += Vector2.left * speed * Time.deltaTime;
yield return null;
}
Destroy(obj);
}
// 记录最近的 4 个 Y 坐标
Queue<float> lastYList = new Queue<float>();
int maxTrackCount = 4; // 记录最近的 4 个 Y 坐标
float GetRandomY(float panelHeight, float minDifference)
{
float randomY = Random.Range(-panelHeight / 2f, panelHeight / 2f);
// 检查与历史记录中的 Y 坐标差是否小于 minDifference
while (lastYList.Any(y => Mathf.Abs(randomY - y) < minDifference))
{
randomY = Random.Range(-panelHeight / 2f, panelHeight / 2f);
}
// 更新 Y 坐标历史记录
if (lastYList.Count >= maxTrackCount)
{
lastYList.Dequeue(); // 移除最旧的 Y 坐标
}
lastYList.Enqueue(randomY); // 添加当前生成的 Y 坐标到队列
return randomY;
}
}