using System; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Serialization; namespace SLSUtilities.FunctionalAnimation { [Flags] public enum FuncAnimDisruptionCause { None = 0, NaturalEnd = 1 << 0, // 动画自然播放完毕 SelfOverride = 1 << 1, // 自身通过 Play() 切入下一个动作 ExternalInterrupt = 1 << 2,// 被外部事件强制打断(如受伤、死亡、被控制) ManualStop = 1 << 3, // 通过 Stop() 被强制停止 Any = ~0 // 任意原因 } /// /// (全新) 自定义Attribute,用于为事件指定一个在时间轴上的颜色 /// [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] public sealed class EventColorAttribute : Attribute { public Color Color { get; } public EventColorAttribute(float r, float g, float b, float a = 1.0f) { this.Color = new Color(r, g, b, a); } } /// /// 所有技能事件负载(Payload)的抽象基类。 /// 技能事件的具体逻辑和参数都定义在它的子类中。 /// [Serializable] [HideReferenceObjectPicker] public abstract class FuncAnimPayloadBase { [Tooltip("是否静默执行该事件(不触发任何反馈)")] [HorizontalGroup("Base", MarginLeft = 4, LabelWidth = 50)] public bool mute = false; [Tooltip("针对Loop动画,只执行一次(循环时不再重复触发)")] [HorizontalGroup("Base", LabelWidth = 50)] [ShowIf("IsLooping")] public bool isOnce = true; protected bool IsLooping => parentData != null && parentData.animationClip != null && parentData.animationClip.isLooping; [HorizontalGroup("Base", LabelWidth = 120)] public bool advancedSettings = false; [FormerlySerializedAs("eventName")] [Tooltip("在时间轴上显示的事件名称 (如果为空,则显示类名)")] [HideInInspector] public string displayEventName; [ShowIf("advancedSettings")] public string customEventName; public string EventName { get => (advancedSettings && string.IsNullOrEmpty(customEventName)) ? displayEventName : customEventName; set { displayEventName = value; customEventName = value; } } [Tooltip("仅当该载荷作为打断事件(Disruption / End Event)时生效:因为这些中断原因被打断时,才触发这个事件")] [PropertyOrder(999)] [ShowIf("advancedSettings")] public FuncAnimDisruptionCause validDisruptionCauses = FuncAnimDisruptionCause.Any; [NonSerialized] public bool hasExecuted = false; public bool CanExecuteOnDisruption(FuncAnimDisruptionCause cause) { return (validDisruptionCauses & cause) != 0; } [NonSerialized] public FuncAnimData parentData; [NonSerialized] public RuntimeFuncAnim runtimeFuncAnim; protected IFuncAnimExecutor Executor => runtimeFuncAnim?.executor; protected FuncAnimPayloadBase() { } public virtual void Invoke() { } /// /// 创建此 Payload 的独立副本,使其拥有独立的 runtimeFuncAnim 引用。 /// 子类如果包含运行时可变的引用类型字段(如 List),应 override 此方法进行深拷贝。 /// public virtual FuncAnimPayloadBase DeepClone() { return (FuncAnimPayloadBase)MemberwiseClone(); } public virtual string NameForInspector => GetType().Name; } [Serializable] public abstract class FuncAnimPayloadBase : FuncAnimPayloadBase { public T result; protected FuncAnimPayloadBase() { } public new virtual T Invoke() { return result; } } /// /// 一个简单的日志事件,用于调试 /// [EventColor(1.0f, 1.0f, 0.2f)] public class LogEvent : FuncAnimPayloadBase { public string message = "Hello World!"; public override void Invoke() { Debug.Log(message); } } /// /// 运行时动态注入的行为事件载荷。 /// public class InvokeAction : FuncAnimPayloadBase { private readonly Action action; public InvokeAction(Action action) { this.action = action; } public override void Invoke() { action?.Invoke(); } } }