新Feedback系统
This commit is contained in:
151
Assets/Scripts/MainGame/Effects/Feedbacks/PlayFeedbackPayload.cs
Normal file
151
Assets/Scripts/MainGame/Effects/Feedbacks/PlayFeedbackPayload.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using Cielonos.MainGame.Characters;
|
||||
using Cielonos.MainGame.Characters.Inventory;
|
||||
using Sirenix.OdinInspector;
|
||||
using SLSUtilities.Feedback;
|
||||
using SLSUtilities.FunctionalAnimation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cielonos.MainGame.Effects.Feedback
|
||||
{
|
||||
/// <summary>
|
||||
/// FuncAnim Payload 集成层:在动画事件触发时播放指定的 FeedbackData。
|
||||
/// 放入 FuncAnimData 的 animEvents 中,Invoke() 时自动通过角色/物品的
|
||||
/// FeedbackSubcontroller 播放,获得正确的时间缩放和 owner Transform。
|
||||
///
|
||||
/// 支持两种来源模式:
|
||||
/// 1. Direct:直接引用一个 FeedbackData 资产
|
||||
/// 2. ByName:从执行者的 FeedbackSubcontroller 中按名称查找
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[EventColor(0.4f, 0.8f, 1.0f)]
|
||||
public class PlayFeedbackPayload : FuncAnimPayloadBase
|
||||
{
|
||||
public override string NameForInspector => "Play Feedback";
|
||||
|
||||
public enum SourceMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 直接引用 FeedbackData 资产。
|
||||
/// </summary>
|
||||
Direct,
|
||||
|
||||
/// <summary>
|
||||
/// 从执行者的 FeedbackDataCollection 中按 feedbackName 查找。
|
||||
/// </summary>
|
||||
ByName
|
||||
}
|
||||
|
||||
[Title("Feedback Source")]
|
||||
public SourceMode sourceMode = SourceMode.Direct;
|
||||
|
||||
/// <summary>
|
||||
/// Direct 模式下直接引用的 FeedbackData 资产。
|
||||
/// </summary>
|
||||
[ShowIf("sourceMode", SourceMode.Direct)]
|
||||
[LabelText("Feedback Data")]
|
||||
public FeedbackData feedbackData;
|
||||
|
||||
/// <summary>
|
||||
/// ByName 模式下按名称查找的 feedbackName。
|
||||
/// </summary>
|
||||
[ShowIf("sourceMode", SourceMode.ByName)]
|
||||
[LabelText("Feedback Name")]
|
||||
public string feedbackName;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在播放前停止同名/同 Data 的正在播放的反馈。
|
||||
/// </summary>
|
||||
[Title("Options")]
|
||||
[LabelText("Stop Previous")]
|
||||
public bool stopPrevious;
|
||||
|
||||
public override void Invoke()
|
||||
{
|
||||
FeedbackData data = ResolveFeedbackData();
|
||||
if (data == null)
|
||||
{
|
||||
Debug.LogWarning($"[PlayFeedbackPayload] Cannot resolve FeedbackData. " +
|
||||
$"Mode: {sourceMode}, Name: {feedbackName}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 尝试通过角色/物品的 FeedbackSubcontroller 播放(获得正确的 timeProvider 和 owner)
|
||||
if (TryPlayViaSubcontroller(data)) return;
|
||||
|
||||
// 回退到全局 FeedbackManager
|
||||
if (FeedbackManager.Instance != null)
|
||||
{
|
||||
FeedbackManager.Instance.Play(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[PlayFeedbackPayload] No FeedbackSubcontroller or FeedbackManager available.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 sourceMode 解析实际的 FeedbackData。
|
||||
/// </summary>
|
||||
private FeedbackData ResolveFeedbackData()
|
||||
{
|
||||
if (sourceMode == SourceMode.Direct)
|
||||
{
|
||||
return feedbackData;
|
||||
}
|
||||
|
||||
// ByName 模式:从执行者获取 FeedbackDataCollection 并查找
|
||||
FeedbackDataCollection collection = GetCollectionFromExecutor();
|
||||
if (collection != null && collection.TryGet(feedbackName, out FeedbackData result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试通过角色或物品的 FeedbackSubcontroller 播放。
|
||||
/// </summary>
|
||||
private bool TryPlayViaSubcontroller(FeedbackData data)
|
||||
{
|
||||
if (character == null) return false;
|
||||
|
||||
// 角色层级
|
||||
if (character is CharacterBase characterBase && characterBase.feedbackSc != null)
|
||||
{
|
||||
characterBase.feedbackSc.PlayFeedback(data, stopPrevious);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 物品层级
|
||||
if (character is ItemBase itemBase && itemBase.feedbackSc != null)
|
||||
{
|
||||
itemBase.feedbackSc.PlayFeedback(data, stopPrevious);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从执行者获取 FeedbackDataCollection。
|
||||
/// </summary>
|
||||
private FeedbackDataCollection GetCollectionFromExecutor()
|
||||
{
|
||||
if (character == null) return null;
|
||||
|
||||
if (character is CharacterBase characterBase && characterBase.feedbackSc != null)
|
||||
{
|
||||
return characterBase.feedbackSc.feedbackDataCollection;
|
||||
}
|
||||
|
||||
if (character is ItemBase itemBase && itemBase.feedbackSc != null)
|
||||
{
|
||||
return itemBase.feedbackSc.feedbackDataCollection;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user