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 { /// /// FuncAnim Payload 集成层:在动画事件触发时播放指定的 FeedbackData。 /// 放入 FuncAnimData 的 animEvents 中,Invoke() 时自动通过角色/物品的 /// FeedbackSubcontroller 播放,获得正确的时间缩放和 owner Transform。 /// /// 支持两种来源模式: /// 1. Direct:直接引用一个 FeedbackData 资产 /// 2. ByName:从执行者的 FeedbackSubcontroller 中按名称查找 /// [Serializable] [EventColor(0.4f, 0.8f, 1.0f)] public class PlayFeedbackPayload : FuncAnimPayloadBase { public override string NameForInspector => "Play Feedback"; public enum SourceMode { /// /// 直接引用 FeedbackData 资产。 /// Direct, /// /// 从执行者的 FeedbackDataCollection 中按 feedbackName 查找。 /// ByName } [Title("Feedback Source")] public SourceMode sourceMode = SourceMode.Direct; /// /// Direct 模式下直接引用的 FeedbackData 资产。 /// [ShowIf("sourceMode", SourceMode.Direct)] [LabelText("Feedback Data")] public FeedbackData feedbackData; /// /// ByName 模式下按名称查找的 feedbackName。 /// [ShowIf("sourceMode", SourceMode.ByName)] [LabelText("Feedback Name")] public string feedbackName; /// /// 是否在播放前停止同名/同 Data 的正在播放的反馈。 /// [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."); } } /// /// 根据 sourceMode 解析实际的 FeedbackData。 /// 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; } /// /// 尝试通过角色或物品的 FeedbackSubcontroller 播放。 /// 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; } /// /// 从执行者获取 FeedbackDataCollection。 /// 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; } } }