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();
}
}
}