2026-04-12 02:11:15 -04:00
|
|
|
|
using System;
|
|
|
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SLSUtilities.Feedback
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 反馈播放上下文,传递给每个 FeedbackAction 的生命周期回调。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public struct FeedbackContext
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 当前播放器实例。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public FeedbackPlayer player;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 触发者的 Transform(可选)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Transform owner;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 当前帧经过时间缩放处理后的 deltaTime。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float deltaTime;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Clip 已播放时间(秒)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float elapsedTime;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Clip 总时长(秒)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float duration;
|
2026-04-18 13:57:19 -04:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 当前 Clip 的综合时间缩放系数(含 Global/Group/Local),由 FeedbackPlayer 每帧动态计算。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float timeScale;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 当前 Clip 是否动态获取当前的时间缩放
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public FeedbackTimeSettings timeSettings;
|
2026-04-12 02:11:15 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 所有反馈动作的抽象基类,定义生命周期回调。
|
|
|
|
|
|
/// 使用 Odin 的序列化路径实现多态序列化(SerializedScriptableObject)。
|
|
|
|
|
|
/// Odin 会自动为此抽象类型的字段显示多态类型选择器。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public abstract class FeedbackActionBase
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Inspector 中显示的名称。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual string DisplayName => GetType().Name;
|
|
|
|
|
|
|
2026-04-18 13:57:19 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 是否忽略时间缩放。如果为true,此Action将使用原始deltaTime,不受TimeScale影响。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual bool IgnoreTimeScale => false;
|
|
|
|
|
|
|
2026-04-12 02:11:15 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 初始化,FeedbackPlayer 开始播放此 Clip 时调用。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual void OnStart(FeedbackContext context) { }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 每帧更新,normalizedTime 为 Clip 内的归一化进度 [0,1]。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual void OnUpdate(FeedbackContext context, float normalizedTime) { }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Clip 自然结束时调用。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual void OnEnd(FeedbackContext context) { }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 被打断时调用,负责立即复位到初始状态。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual void OnInterrupt(FeedbackContext context) { }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用于验证配置是否正确(Editor 环境)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual bool Validate(out string error)
|
|
|
|
|
|
{
|
|
|
|
|
|
error = null;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用于 Editor 预览(Runtime 也可用)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public virtual void Preview() { }
|
2026-04-18 13:57:19 -04:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据归一化时间采样曲线并映射到实际值范围。
|
|
|
|
|
|
/// 如果 relativeToInitial 为 true,结果会叠加在 initialValue 上。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="shakeCurve">震动曲线,X 轴为归一化时间 [0,1],Y 轴为震动强度 [0,1]。</param>
|
|
|
|
|
|
/// <param name="remapMin">曲线值 0 对应的实际数值。</param>
|
|
|
|
|
|
/// <param name="remapMax">曲线值 1 对应的实际数值。</param>
|
|
|
|
|
|
/// <param name="relativeToInitial">是否在初始值上叠加(而非替换)。</param>
|
|
|
|
|
|
/// <param name="normalizedTime">归一化时间 [0,1]</param>
|
|
|
|
|
|
/// <param name="initialValue">初始值(OnStart 时记录)</param>
|
|
|
|
|
|
/// <returns>映射后的最终数值</returns>
|
|
|
|
|
|
protected virtual float EvaluateShake(AnimationCurve shakeCurve, float remapMin, float remapMax, bool relativeToInitial,
|
|
|
|
|
|
float normalizedTime, float initialValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
float curveValue = shakeCurve.Evaluate(normalizedTime);
|
|
|
|
|
|
float remappedValue = Mathf.LerpUnclamped(remapMin, remapMax, curveValue);
|
|
|
|
|
|
|
|
|
|
|
|
if (relativeToInitial)
|
|
|
|
|
|
{
|
|
|
|
|
|
return initialValue + remappedValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return remappedValue;
|
|
|
|
|
|
}
|
2026-04-12 02:11:15 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|