hch
2025-09-12 5f38a82168cbca71d03822fdcbeaf3f1cd3905dd
Main/System/Battle/Motion/MotionBase.cs
@@ -25,9 +25,11 @@
    public Action OnAttackAnimationComplete;
    public Action OnHitAnimationComplete;
    public Action<string> onAnimationComplete;
    private List<Action> runActionList = new List<Action>();
    #region 组件引用
    protected SkeletonGraphic skeletonGraphic;
    protected Spine.AnimationState spineAnimationState;
    protected Spine.Skeleton skeleton;
@@ -42,6 +44,7 @@
    #endregion
    private Spine.TrackEntry currentTrackEntry;
    #region 初始化方法
@@ -134,6 +137,16 @@
        return currentTrackEntry;
    }
    private void RunAction(Action _action)
    {
        runActionList.Add(_action);
    }
    private void RemoveRunAction(Action _action)
    {
        runActionList.Remove(_action);
    }
    public Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, Action _onComplete = null)
    {
        // 参数校验
@@ -174,12 +187,10 @@
        }
        // 关键帧参数
        float fps = BattleConst.skillMotionFps;
        float middleBeginTime = skillConfig.StartupFrames / fps;
        int loopCount = skillConfig.LoopCount;
        int[] activeFrames = skillConfig.ActiveFrames;
        int activeFrameCount = activeFrames.Length;
        float recoveryFrameTime = skillConfig.RecoveryFrames / fps;
        float recoveryFrame = skillConfig.RecoveryFrames;
        // 播放动画
        var skillTrackEntry = spineAnimationState.SetAnimation(0, anim, false);
@@ -198,21 +209,23 @@
        skillBase.OnSkillStart();
        // 动画帧更新处理
        Spine.Unity.UpdateBonesDelegate updateLocalHandler = null;
        updateLocalHandler = (ISkeletonAnimation animated) =>
        int triggerMFEndCount = 0;
        Action updateLocalHandler = null;
        updateLocalHandler = () =>
        {
            if (isFinish) return;
            float trackTime = skillTrackEntry.TrackTime;
            float frame = (skillTrackEntry.TrackTime * (float)BattleConst.skillMotionFps);
            // 前摇结束(只触发一次)
            if (!beginPhaseTriggered && trackTime >= middleBeginTime && curLoop == 0)
            if (!beginPhaseTriggered && frame >= skillConfig.StartupFrames && curLoop == 0)
            {
                beginPhaseTriggered = true;
                skillBase.OnStartSkillFrameEnd();
            }
            // 中摇开始(每轮loop的开始,只触发一次)
            if (!middleFrameStarted && trackTime >= middleBeginTime && curLoop <= loopCount)
            if (!middleFrameStarted && frame >= skillConfig.StartupFrames && curLoop <= loopCount)
            {
                middleFrameStarted = true;
                skillBase.OnMiddleFrameStart(curLoop);
@@ -221,10 +234,10 @@
            // 多段攻击帧触发
            for (int hitIndex = 0; hitIndex < activeFrameCount; hitIndex++)
            {
                float activeFrameTime = activeFrames[hitIndex] / fps;
                if (!triggeredActiveFrame[hitIndex] && trackTime >= activeFrameTime)
                float activeFrame = activeFrames[hitIndex];
                if (!triggeredActiveFrame[hitIndex] && frame >= activeFrame)
                {
                    skillBase.OnMiddleFrameEnd(curLoop, hitIndex);
                    skillBase.OnMiddleFrameEnd(curLoop, triggerMFEndCount++);
                    triggeredActiveFrame[hitIndex] = true;
                }
            }
@@ -250,7 +263,7 @@
                if (curLoop < loopCount)
                {
                    // 重新设置到第一次的中摇时间
                    skillTrackEntry.TrackTime = middleBeginTime;
                    skillTrackEntry.TrackTime = skillConfig.StartupFrames / BattleConst.skillMotionFps;
                    beginPhaseTriggered = false;
                }
                else
@@ -264,16 +277,16 @@
            // 收尾阶段:OnFinalFrameStart 和 OnFinalFrameEnd
            if (curLoop >= loopCount)
            {
                if (!finalFrameStarted && trackTime >= recoveryFrameTime)
                if (!finalFrameStarted && frame >= recoveryFrame)
                {
                    finalFrameStarted = true;
                    skillBase.OnFinalFrameStart();
                }
                if (finalFrameStarted && !finalFrameEnded && trackTime >= recoveryFrameTime)
                if (finalFrameStarted && !finalFrameEnded && frame >= recoveryFrame)
                {
                    finalFrameEnded = true;
                    skillBase.OnFinalFrameEnd();
                    skeletonGraphic.UpdateLocal -= updateLocalHandler;
                    RemoveRunAction(updateLocalHandler);
                    isFinish = true;
                }
            }
@@ -284,7 +297,8 @@
            trackEntryCompleteDict[currentTrackEntry] = _onComplete;
        }
        skeletonGraphic.UpdateLocal += updateLocalHandler;
        RunAction(updateLocalHandler);
        return skillTrackEntry;
    }
@@ -334,7 +348,10 @@
    public virtual void Run()
    {
        for (int i = runActionList.Count - 1; i >= 0; i--)
        {
            runActionList[i]?.Invoke();
        }
    }
    public virtual void Pause()
@@ -352,6 +369,7 @@
    public void HaveRest()
    {
        trackEntryCompleteDict.Clear();
        runActionList.Clear();
        PlayAnimation(MotionName.idle, true);
    }