using System; using System.Collections; using Convention; using UnityEngine; namespace Demo.Game { public abstract class IEffectHookObject : ScriptableObject, IHookInteraction { public enum InteractiveEffectType { VisibleDuration = 3, InteractiveDuration = 2, InteractableScoreInterval = 1, InteractableIntervalThatCanScoreBest = 0 } [Content, SerializeField] private IInteraction m_MyInteractionModule; [Content, SerializeField] private InteractiveEffectType MyInteractiveLevel = default; private IInteraction MyInteractionModule { get { if (m_MyInteractionModule == null) m_MyInteractionModule = Parent.GetComponent(); return m_MyInteractionModule; } set { m_MyInteractionModule = value; } } public abstract void OnInit(); public abstract void OnBegin(); public abstract void OnEnd(); protected override IEnumerator DoSomethingDuringApplyScript() { yield return base.DoSomethingDuringApplyScript(); switch (MyInteractiveLevel) { case InteractiveEffectType.VisibleDuration: { MyInteractionModule.VisibleDurationBeforeEvent.AddListener(OnInit); MyInteractionModule.VisibleDurationBeginEvent.AddListener(OnBegin); MyInteractionModule.VisibleDurationEndEvent.AddListener(OnEnd); } break; case InteractiveEffectType.InteractiveDuration: { MyInteractionModule.InteractiveDurationBeforeEvent.AddListener(OnInit); MyInteractionModule.InteractiveDurationBeginEvent.AddListener(OnBegin); MyInteractionModule.InteractiveDurationEndEvent.AddListener(OnEnd); } break; case InteractiveEffectType.InteractableScoreInterval: { MyInteractionModule.InteractableScoreIntervalBeforeEvent.AddListener(OnInit); MyInteractionModule.InteractableScoreIntervalBeginEvent.AddListener(OnBegin); MyInteractionModule.InteractableScoreIntervalEndEvent.AddListener(OnEnd); } break; case InteractiveEffectType.InteractableIntervalThatCanScoreBest: { MyInteractionModule.InteractableIntervalThatCanScoreBestBeforeEvent.AddListener(OnInit); MyInteractionModule.InteractableIntervalThatCanScoreBestBeginEvent.AddListener(OnBegin); MyInteractionModule.InteractableIntervalThatCanScoreBestEndEvent.AddListener(OnEnd); } break; } } public override IEnumerator UnloadScript() { // 如果是父物体那么在此处执行前就会重新生成对应的event // 但通过绑定得到的其他物体并不能保证顺序关系 // 因此此处仍需要对象自行清理 switch (MyInteractiveLevel) { case InteractiveEffectType.VisibleDuration: { MyInteractionModule.VisibleDurationBeforeEvent.RemoveListener(OnInit); MyInteractionModule.VisibleDurationBeginEvent.RemoveListener(OnBegin); MyInteractionModule.VisibleDurationEndEvent.RemoveListener(OnEnd); } break; case InteractiveEffectType.InteractiveDuration: { MyInteractionModule.InteractiveDurationBeforeEvent.RemoveListener(OnInit); MyInteractionModule.InteractiveDurationBeginEvent.RemoveListener(OnBegin); MyInteractionModule.InteractiveDurationEndEvent.RemoveListener(OnEnd); } break; case InteractiveEffectType.InteractableScoreInterval: { MyInteractionModule.InteractableScoreIntervalBeforeEvent.RemoveListener(OnInit); MyInteractionModule.InteractableScoreIntervalBeginEvent.RemoveListener(OnBegin); MyInteractionModule.InteractableScoreIntervalEndEvent.RemoveListener(OnEnd); } break; case InteractiveEffectType.InteractableIntervalThatCanScoreBest: { MyInteractionModule.InteractableIntervalThatCanScoreBestBeforeEvent.RemoveListener(OnInit); MyInteractionModule.InteractableIntervalThatCanScoreBestBeginEvent.RemoveListener(OnBegin); MyInteractionModule.InteractableIntervalThatCanScoreBestEndEvent.RemoveListener(OnEnd); } break; } yield return base.UnloadScript(); } /// /// 绑定IInteraction对象,若不手动绑定则会自动绑定到父物体的IInteraction /// /// [Convention.RScript.Variable.Attr.Method] public void Bind(IInteraction target) { MyInteractionModule = target; } /// /// 设置监听状态,当目标进入指定监听的状态时触发启动事件,退出时触发结束事件 /// /// VisibleDuration,InteractiveDuration,InteractableScoreInterval,InteractableIntervalThatCanScoreBest [Convention.RScript.Variable.Attr.Method] public void SetInteractiveEffectType(InteractiveEffectType type) { MyInteractiveLevel = type; } } }