using UnityEngine; /// /// 战神激光 loop 状态通知(Animator 状态机行为)。 /// 用法:打开战神的 Animator Controller → 选中激光状态(Fire1) → Inspector 底部 /// Add Behaviour → ZhanShenLaserLoopSMB。 /// ⭐ 通知时机 = 过渡(Fire0→Fire1 crossfade)播放完成之后 + prepPortion 比例处: /// prepPortion=0 即"过渡完成后立即放行激光特效"(提前结束 laserFXDelay 兜底等待)。 /// 注意 OnStateEnter 在过渡开始瞬间就会触发(此时 crossfade 尚未播完),不能在那里通知; /// 若动画带准备段,可把 prepPortion 设为准备段占一圈的比例(从过渡完成起算)。 /// 重新进入状态(停火再开火 / Fire0-Fire1 切换)会重新等待并通知。 /// public class ZhanShenLaserLoopSMB : StateMachineBehaviour { [Tooltip("0=过渡完成后立即显示(默认);若动画带准备段,填准备段占一圈的比例(从过渡完成起算)")] [Range(0f, 1f)] public float prepPortion = 0f; private bool _notified; public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { // ⭐ OnStateEnter 在过渡(crossfade)开始瞬间就触发,此时状态画面还没完全切过来,不能在这里通知; // 只重置等待标记,统一交给 OnStateUpdate 等"过渡播完 + prepPortion"后再通知 _notified = false; } public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { if (_notified) return; if (animator.IsInTransition(layerIndex)) return; // 过渡没播完不触发(Fire0→Fire1 crossfade 期间) if (stateInfo.normalizedTime < prepPortion) return; _notified = true; NotifyLaserLoopBegin(animator); } private void NotifyLaserLoopBegin(Animator animator) { // 战神实例上的 TurretData(向上查找,Animator 挂根/子物体都能找到)→ 通知座位 animator.GetComponentInParent()?.NotifyZhanShenLaserLoopAnim(); } }