1+ using System . Collections . Generic ;
12using AquaMai . Config . Attributes ;
23using HarmonyLib ;
34using MAI2 . Util ;
@@ -15,8 +16,8 @@ namespace AquaMai.Mods.Utils;
1516public 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