Files
Cielonos/Assets/Scripts/MainGame/Effects/Feedbacks/PlayFeedbackPayload.cs
SoulliesOfficial 41140a2017 新Feedback系统
2026-04-12 02:11:15 -04:00

152 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}