Files
Cielonos/Assets/Scripts/MainGame/Effects/Feedbacks/PlayFeedbackPayload.cs

152 lines
4.9 KiB
C#
Raw Normal View History

2026-04-12 02:11:15 -04:00
using System;
using Cielonos.MainGame.Characters;
2026-05-23 08:27:50 -04:00
using Cielonos.MainGame.Inventory;
2026-04-12 02:11:15 -04:00
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)
{
2026-06-05 04:21:00 -04:00
if (Executor == null) return false;
2026-04-12 02:11:15 -04:00
// 角色层级
2026-06-05 04:21:00 -04:00
if (Executor is CharacterBase characterBase && characterBase.feedbackSc != null)
2026-04-12 02:11:15 -04:00
{
characterBase.feedbackSc.PlayFeedback(data, stopPrevious);
return true;
}
// 物品层级
2026-06-05 04:21:00 -04:00
if (Executor is ItemBase itemBase && itemBase.feedbackSc != null)
2026-04-12 02:11:15 -04:00
{
itemBase.feedbackSc.PlayFeedback(data, stopPrevious);
return true;
}
return false;
}
/// <summary>
/// 从执行者获取 FeedbackDataCollection。
/// </summary>
private FeedbackDataCollection GetCollectionFromExecutor()
{
2026-06-05 04:21:00 -04:00
if (Executor == null) return null;
2026-04-12 02:11:15 -04:00
2026-06-05 04:21:00 -04:00
if (Executor is CharacterBase characterBase && characterBase.feedbackSc != null)
2026-04-12 02:11:15 -04:00
{
return characterBase.feedbackSc.feedbackDataCollection;
}
2026-06-05 04:21:00 -04:00
if (Executor is ItemBase itemBase && itemBase.feedbackSc != null)
2026-04-12 02:11:15 -04:00
{
return itemBase.feedbackSc.feedbackDataCollection;
}
return null;
}
}
}