using System.Collections.Generic; using Lean.Pool; using UnityEngine; namespace Ichni.RhythmGame { public class NoteManager : MonoBehaviour { #region [核心管家字段] Fields // 挂起队列:存放还未进入判定时间序列休眠的预设 private List<(float activationTime, NoteBase note)> _pendingNotes = new List<(float, NoteBase)>(); // 活跃队列:存活在场上的有效音符,统一进行中央更新 private List _activeNotes = new List(500); private int _nextNoteIndex = 0; #endregion #region [队列注册与控制] Registration public void RegisterNote(NoteBase note, float activationTime) { _pendingNotes.Add((activationTime, note)); } public void AllNotesRegistered() { _pendingNotes.Sort((a, b) => a.activationTime.CompareTo(b.activationTime)); _nextNoteIndex = 0; } #endregion #region [中央集权主循环] Manager-Driven Tick public void ManualUpdate(float currentSongTime) { if (!GameManager.Instance.songPlayer.isUpdating) return; // 1. 唤醒 pending 并推进入场 while (_nextNoteIndex < _pendingNotes.Count && currentSongTime >= _pendingNotes[_nextNoteIndex].activationTime) { NoteBase noteToActivate = _pendingNotes[_nextNoteIndex].note; noteToActivate.gameObject.SetActive(true); _activeNotes.Add(noteToActivate); _nextNoteIndex++; } // 2. 集中处理场内活跃 Note (倒序遍历以防越界) for (int i = _activeNotes.Count - 1; i >= 0; i--) { if (!_activeNotes[i].ManualUpdate(currentSongTime)) { _activeNotes.RemoveAt(i); } } } public void ManualLateUpdate(float currentSongTime) { if (!GameManager.Instance.songPlayer.isUpdating) return; for (int i = _activeNotes.Count - 1; i >= 0; i--) { if (_activeNotes[i] is Hold hold) { hold.isHolding = false; } } } #endregion #region [生命回收] Pool Management public void DespawnNote(NoteBase note) { if (note.gameObject.activeSelf) { LeanPool.Despawn(note.gameObject); } } #endregion } }