using System; using Cielonos.MainGame.Characters; using Sirenix.OdinInspector; using SLSUtilities.FunctionalAnimation; using UnityEngine; namespace Cielonos.MainGame.FunctionalAnimation { [Serializable] [EventColor(0.2f, 0.8f, 0.6f)] public class SetFuncAnimSpeed : FuncAnimPayloadBase { public override bool IsCombatOnly => false; public enum SpeedApplyMode { [LabelText("直接覆盖速度倍率 (Override)")] Override, [LabelText("与当前速度相乘 (Multiply)")] Multiply } [Tooltip("速度应用模式。Override直接改变播放器速度;Multiply可以在当前速度基础上乘以比例变化。")] public SpeedApplyMode applyMode = SpeedApplyMode.Override; [Tooltip("是否从行为树获取速度参数")] public bool getFromBehaviorTree = false; [Tooltip("行为树中的 Float 变量名称")] [ShowIf("getFromBehaviorTree")] public string speedVariableName = "FuncAnimSpeed"; [Tooltip("目标播放速度倍率")] [HideIf("getFromBehaviorTree")] public float targetSpeed = 1.0f; public override void Invoke() { if (Character == null || Character.animationSc == null) return; FuncAnimSubmodule funcAnimSm = Character.animationSc.fullBodyFuncAnimSm; if (funcAnimSm == null || !funcAnimSm.IsPlaying) return; float speedValue = targetSpeed; if (getFromBehaviorTree) { BehaviorSubcontroller behaviorSc = (Character as Automata)?.behaviorSc; if (behaviorSc != null && behaviorSc.mainBehaviorTree != null) { var speedVar = behaviorSc.mainBehaviorTree.GetVariable(speedVariableName); if (speedVar != null) { speedValue = speedVar.Value; } } } // 1. 设置 C# 播放器的固有速度 if (applyMode == SpeedApplyMode.Override) { funcAnimSm.currentPlaySpeedMultiplier = speedValue; } else { funcAnimSm.currentPlaySpeedMultiplier *= speedValue; } // 2. 刷新 Animator State 中的 ActionSpeed 参数 try { float overridePlaySpeed = funcAnimSm.currentData.animInfo.overridePlaySpeed; float finalActionSpeed = overridePlaySpeed * funcAnimSm.currentPlaySpeedMultiplier; funcAnimSm.Animator.SetFloat("ActionSpeed", finalActionSpeed); } catch { /* 忽略状态机中未配置 ActionSpeed 变量的情况 */ } } } }