using System.Collections; using System.Collections.Generic; using System.Linq; using UniRx; using UnityEngine; namespace Ichni.RhythmGame { public class NoteManager : MonoBehaviour { public static NoteManager instance; public List<(NoteBase note, float activationTime, float finishTime)> pendingNotes = new List<(NoteBase, float, float)>(); private List<(NoteBase note1, bool isActive, float activationTime)> ProcessingNotes = new List<(NoteBase, bool, float)>(); public void RegisterNote(NoteBase note, float activationTime, float finishTime) { pendingNotes.Add((note, activationTime, finishTime)); AllNotesRegistered(); print($"Registered note {note.elementName} with activation time {activationTime} and finish time {finishTime}"); } public void Awake() { instance = this; } public void ChangeNoteInfo(NoteBase note, float activationTime, float finishTime) { int idx = pendingNotes.FindIndex(i => i.note == note); if (idx != -1) { var one = pendingNotes[idx]; one.finishTime = finishTime; one.activationTime = activationTime; pendingNotes[idx] = one; AllNotesRegistered(); } } // 在所有物体注册完毕后,对列表进行一次排序 public void AllNotesRegistered() { pendingNotes.Sort((a, b) => a.activationTime.CompareTo(b.activationTime)); } void Update() { float currentTime = EditorManager.instance.songInformation.songTime; foreach (var item in ProcessingNotes) { var (note, isActive, activationTime) = item; if (!isActive) note.Update(); note.gameObject.SetActive(isActive); if (isActive) { note.Update(); if (currentTime < activationTime) { note.noteVisual?.Recover(); } else if (note is Hold hold && currentTime >= hold.holdEndTime) { hold.SetFinishEffects(); } } } ProcessingNotes.Clear(); // 一次性移除所有 null 项 pendingNotes.RemoveAll(item => item.note == null); foreach (var item in pendingNotes) { var (note, activationTime, finishTime) = item; bool shouldBeActive = currentTime >= activationTime && currentTime <= finishTime; bool isActive = note.gameObject.activeSelf; if (shouldBeActive && !isActive) { ProcessingNotes.Add((note, true, activationTime)); } else if (!shouldBeActive && isActive) { ProcessingNotes.Add((note, false, activationTime)); } } } } }