2025-07-21 05:42:20 -04:00
|
|
|
using System.Collections.Generic;
|
2026-03-14 03:13:10 -04:00
|
|
|
using Lean.Pool;
|
2025-07-21 05:42:20 -04:00
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace Ichni.RhythmGame
|
|
|
|
|
{
|
|
|
|
|
public class NoteManager : MonoBehaviour
|
|
|
|
|
{
|
2026-03-14 03:13:10 -04:00
|
|
|
#region [核心管家字段] Fields
|
|
|
|
|
// 挂起队列:存放还未进入判定时间序列休眠的预设
|
|
|
|
|
private List<(float activationTime, NoteBase note)> _pendingNotes = new List<(float, NoteBase)>();
|
|
|
|
|
// 活跃队列:存活在场上的有效音符,统一进行中央更新
|
|
|
|
|
private List<NoteBase> _activeNotes = new List<NoteBase>(500);
|
|
|
|
|
private int _nextNoteIndex = 0;
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region [队列注册与控制] Registration
|
2025-07-21 05:42:20 -04:00
|
|
|
public void RegisterNote(NoteBase note, float activationTime)
|
|
|
|
|
{
|
2026-03-14 03:13:10 -04:00
|
|
|
_pendingNotes.Add((activationTime, note));
|
2025-07-21 05:42:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AllNotesRegistered()
|
|
|
|
|
{
|
2026-03-14 03:13:10 -04:00
|
|
|
_pendingNotes.Sort((a, b) => a.activationTime.CompareTo(b.activationTime));
|
|
|
|
|
_nextNoteIndex = 0;
|
2025-07-21 05:42:20 -04:00
|
|
|
}
|
2026-03-14 03:13:10 -04:00
|
|
|
#endregion
|
2025-07-21 05:42:20 -04:00
|
|
|
|
2026-03-14 03:13:10 -04:00
|
|
|
#region [中央集权主循环] Manager-Driven Tick
|
|
|
|
|
public void ManualUpdate(float currentSongTime)
|
2025-07-21 05:42:20 -04:00
|
|
|
{
|
2026-03-14 03:13:10 -04:00
|
|
|
if (!GameManager.Instance.songPlayer.isUpdating) return;
|
|
|
|
|
|
|
|
|
|
// 1. 唤醒 pending 并推进入场
|
|
|
|
|
while (_nextNoteIndex < _pendingNotes.Count &&
|
|
|
|
|
currentSongTime >= _pendingNotes[_nextNoteIndex].activationTime)
|
2025-07-21 05:42:20 -04:00
|
|
|
{
|
2026-03-14 03:13:10 -04:00
|
|
|
NoteBase noteToActivate = _pendingNotes[_nextNoteIndex].note;
|
|
|
|
|
noteToActivate.gameObject.SetActive(true);
|
|
|
|
|
_activeNotes.Add(noteToActivate);
|
|
|
|
|
_nextNoteIndex++;
|
2025-07-21 05:42:20 -04:00
|
|
|
}
|
|
|
|
|
|
2026-03-14 03:13:10 -04:00
|
|
|
// 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)
|
2025-07-21 05:42:20 -04:00
|
|
|
{
|
2026-03-14 03:13:10 -04:00
|
|
|
LeanPool.Despawn(note.gameObject);
|
2025-07-21 05:42:20 -04:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-14 03:13:10 -04:00
|
|
|
#endregion
|
2025-07-21 05:42:20 -04:00
|
|
|
}
|
2026-03-14 03:13:10 -04:00
|
|
|
}
|