Skip to content

Commit dc91896

Browse files
committed
[O] 使用对象池优化性能
1 parent a37e2e7 commit dc91896

File tree

1 file changed

+71
-17
lines changed

1 file changed

+71
-17
lines changed

AquaMai.Mods/Utils/UnstableRate.cs

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using AquaMai.Config.Attributes;
23
using HarmonyLib;
34
using MAI2.Util;
@@ -15,8 +16,8 @@ namespace AquaMai.Mods.Utils;
1516
public class UnstableRate
1617
{
1718
// The playfield goes from bottom left (-1080, -960) to top right (0, 120)
18-
// 由于使用了 local space,所以高度和中心都是 0
19-
private const float BaselineHeight = 0;
19+
// 使用了 local space
20+
private const float BaselineHeight = -70;
2021
private const float BaselineCenter = 0;
2122
private const float BaselineHScale = 25;
2223
private const float CenterMarkerHeight = 20;
@@ -67,6 +68,7 @@ private struct Timing
6768
private static readonly Material LineMaterial = new(Shader.Find("Sprites/Default"));
6869

6970
private static GameObject[] baseObjects = new GameObject[2];
71+
private static LinePool[] linePools = new LinePool[2];
7072

7173
[HarmonyPostfix]
7274
[HarmonyPatch(typeof(GameProcess), "OnStart")]
@@ -80,6 +82,7 @@ public static void OnGameProcessStart(GameProcess __instance, GameMonitor[] ____
8082
var go = new GameObject("[AquaMai] UnstableRate");
8183
go.transform.SetParent(main, false);
8284
baseObjects[i] = go;
85+
linePools[i] = new LinePool(go);
8386
SetupBaseline(go);
8487
}
8588
}
@@ -104,13 +107,13 @@ public static void OnJudge(NoteBase __instance, float ___JudgeTimingDiffMsec)
104107
return;
105108
}
106109

107-
var go = baseObjects[__instance.MonitorId];
108-
if (go == null)
110+
var pool = linePools[__instance.MonitorId];
111+
if (pool == null)
109112
{
110113
return;
111114
}
112-
// Create judgement tick
113-
var line = CreateLine(go);
115+
116+
var line = pool.Get();
114117

115118
line.SetPosition(0, new Vector3(BaselineCenter + BaselineHScale * (msec / TimingBin), BaselineHeight + JudgeHeight, 0));
116119
line.SetPosition(1, new Vector3(BaselineCenter + BaselineHScale * (msec / TimingBin), BaselineHeight - JudgeHeight, 0));
@@ -119,11 +122,12 @@ public static void OnJudge(NoteBase __instance, float ___JudgeTimingDiffMsec)
119122
line.endColor = timing.color;
120123

121124
// Setup fade-out
122-
var judgeTick = line.gameObject.AddComponent<JudgeTick>();
123-
judgeTick.SetLine(line);
124-
125-
// Destroy it once the fade-out is over
126-
Object.Destroy(line.gameObject, JudgeFadeDelay + JudgeFadeTime);
125+
var judgeTick = line.gameObject.GetComponent<JudgeTick>();
126+
if (judgeTick == null)
127+
{
128+
judgeTick = line.gameObject.AddComponent<JudgeTick>();
129+
}
130+
judgeTick.SetLine(line, pool);
127131
}
128132

129133
[HarmonyPostfix]
@@ -202,19 +206,63 @@ private static Timing GetTiming(float msec)
202206
return Miss;
203207
}
204208

205-
// Handles the fade-out of judgment ticks
209+
private class LinePool
210+
{
211+
private readonly Queue<LineRenderer> _pool = new();
212+
private readonly GameObject _parent;
213+
private const int InitialPoolSize = 128;
214+
215+
public LinePool(GameObject parent)
216+
{
217+
_parent = parent;
218+
219+
// 预创建对象
220+
for (int i = 0; i < InitialPoolSize; i++)
221+
{
222+
var line = CreateLine(_parent);
223+
line.gameObject.SetActive(false);
224+
_pool.Enqueue(line);
225+
}
226+
}
227+
228+
public LineRenderer Get()
229+
{
230+
LineRenderer line;
231+
if (_pool.Count > 0)
232+
{
233+
line = _pool.Dequeue();
234+
line.gameObject.SetActive(true);
235+
}
236+
else
237+
{
238+
line = CreateLine(_parent);
239+
}
240+
241+
return line;
242+
}
243+
244+
public void Return(LineRenderer line)
245+
{
246+
line.gameObject.SetActive(false);
247+
_pool.Enqueue(line);
248+
}
249+
}
250+
251+
// 动画
206252
private class JudgeTick : MonoBehaviour
207253
{
208254
private float _elapsedTime;
209255
private LineRenderer _line;
256+
private LinePool _pool;
210257
private Color _initialColor;
211258

212-
public void SetLine(LineRenderer line)
259+
public void SetLine(LineRenderer line, LinePool pool)
213260
{
214261
_line = line;
262+
_pool = pool;
215263
_initialColor = line.startColor;
264+
_elapsedTime = 0;
216265

217-
// We needed to store the full color above, so we didn't apply the alpha before
218266
var color = _initialColor;
219267
color.a *= JudgeAlpha;
220268

@@ -226,13 +274,19 @@ public void Update()
226274
{
227275
_elapsedTime += Time.deltaTime;
228276

229-
// Only start the fade-out after a short delay
230277
if (_elapsedTime < JudgeFadeDelay)
231278
return;
232279

233-
Color color = _initialColor;
280+
var fadeProgress = (_elapsedTime - JudgeFadeDelay) / JudgeFadeTime;
281+
282+
if (fadeProgress >= 1.0f)
283+
{
284+
_pool.Return(_line);
285+
return;
286+
}
234287

235-
color.a = JudgeAlpha * (1.0f - Mathf.Clamp01((_elapsedTime - JudgeFadeDelay) / JudgeFadeTime));
288+
Color color = _initialColor;
289+
color.a = JudgeAlpha * (1.0f - fadeProgress);
236290

237291
_line.startColor = color;
238292
_line.endColor = color;

0 commit comments

Comments
 (0)