108 lines
3.0 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|