Files
2026-07-26 03:44:27 +08:00

108 lines
3.0 KiB
C#

using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 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.
/// </summary>
public sealed class NoteRuntimeTickManager : MonoBehaviour
{
private static NoteRuntimeTickManager instance;
private readonly List<NoteController> noteControllers = new List<NoteController>(256);
private readonly List<HoldNoteController> holdControllers = new List<HoldNoteController>(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<NoteRuntimeTickManager>();
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);
}
}
}