using System; using System.Collections; using System.Collections.Generic; using Ichni.RhythmGame.Beatmap; using Sirenix.OdinInspector; using UniRx; using UnityEngine; namespace Ichni.RhythmGame { public partial class TimeEffectsCollection : GameElement, IHaveTransformSubmodule, IHaveEffectSubmodule, IScheduledElement { #region [暴露属性字段] Essential Configs public float time; //触发效果的时间 #endregion #region [运行时缓存] Cached Effect Lists private List _priorEffects; private List _defaultEffects; private List _lateEffects; #endregion #region [子模块接口] Submodules public TransformSubmodule transformSubmodule { get; set; } public EffectSubmodule effectSubmodule { get; set; } #endregion #region [生命周期] Lifecycle & Factory public static TimeEffectsCollection GenerateElement(string name, Guid guid, List tags, bool isFirstGenerated, GameElement parentElement, float time) { TimeEffectsCollection timeEffectsCollection = Instantiate(GameManager.Instance.basePrefabs.emptyObject).AddComponent(); timeEffectsCollection.Initialize(name, guid, tags, isFirstGenerated, parentElement); timeEffectsCollection.time = time; return timeEffectsCollection; } public override void SetDefaultSubmodules() { transformSubmodule = new TransformSubmodule(this); effectSubmodule = new EffectSubmodule(this); } public override void AfterInitialize() { base.AfterInitialize(); CacheEffectLists(); CoreServices.UpdateScheduler.Register(UpdatePhase.Effect, this); } public override void OnDelete() { base.OnDelete(); CoreServices.UpdateScheduler.Unregister(UpdatePhase.Effect, this); } /// /// 缓存 effectCollection 中的 Prior/Default/Late 列表引用, /// 避免 ScheduledUpdate 中每帧执行 Dictionary string key 查找。 /// private void CacheEffectLists() { if (effectSubmodule?.effectCollection == null) return; effectSubmodule.effectCollection.TryGetValue("Prior", out _priorEffects); effectSubmodule.effectCollection.TryGetValue("Default", out _defaultEffects); effectSubmodule.effectCollection.TryGetValue("Late", out _lateEffects); } #endregion #region [轮询更新] Main Update #region [IScheduledElement] Scheduler Interface public void ScheduledUpdate(UpdatePhase phase, float songTime) { if (effectSubmodule == null) return; UpdateEffectList(_priorEffects, time); UpdateEffectList(_defaultEffects, time); UpdateEffectList(_lateEffects, time); } private static void UpdateEffectList(List effects, float effectTime) { if (effects == null) return; for (int i = 0; i < effects.Count; i++) { effects[i].UpdateEffect(effectTime); } } public bool IsScheduledActive => isActiveAndEnabled; #endregion #endregion } }