using System.Collections.Generic; using UnityEngine; /// /// Centralizes runtime ticking for note controllers so dense charts do not pay one /// MonoBehaviour.Update dispatch per active note/hold segment. Per-note movement /// and judge-zone behavior remains in the original controllers. /// public sealed class NoteRuntimeTickManager : MonoBehaviour { private static NoteRuntimeTickManager instance; private readonly List noteControllers = new List(256); private readonly List holdControllers = new List(512); public static void Register(NoteController controller) { if (controller == null) return; EnsureInstance().RegisterInternal(controller); } public static void Unregister(NoteController controller) { if (controller == null || instance == null) return; instance.noteControllers.Remove(controller); } public static void Register(HoldNoteController controller) { if (controller == null) return; EnsureInstance().RegisterInternal(controller); } public static void Unregister(HoldNoteController controller) { if (controller == null || instance == null) return; instance.holdControllers.Remove(controller); } private static NoteRuntimeTickManager EnsureInstance() { if (instance != null) return instance; var go = new GameObject("NoteRuntimeTickManager"); instance = go.AddComponent(); return instance; } private void Awake() { if (instance == null) { instance = this; } else if (instance != this) { Destroy(gameObject); } } private void OnDestroy() { if (instance == this) instance = null; } private void RegisterInternal(NoteController controller) { if (!noteControllers.Contains(controller)) noteControllers.Add(controller); } private void RegisterInternal(HoldNoteController controller) { if (!holdControllers.Contains(controller)) holdControllers.Add(controller); } private void Update() { float songTime = GameplayClock.NowSongTime; float deltaTime = Time.deltaTime; for (int i = noteControllers.Count - 1; i >= 0; i--) { NoteController controller = noteControllers[i]; if (controller == null || !controller.isActiveAndEnabled) { noteControllers.RemoveAt(i); continue; } controller.ManualTick(songTime); } for (int i = holdControllers.Count - 1; i >= 0; i--) { HoldNoteController controller = holdControllers[i]; if (controller == null || !controller.isActiveAndEnabled) { holdControllers.RemoveAt(i); continue; } controller.ManualTick(songTime, deltaTime); } } }