yyl
2026-02-09 d0dfe302f42f680bd3a84a29b9d58947046403c7
Main/System/Battle/Motion/MotionBase.cs
@@ -160,7 +160,7 @@
        return true;
    }
    public Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, bool isSubSkill, Action onComplete = null)
    public Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, bool isSubSkill, Action onComplete = null)
    {
        if (skillConfig == null)
        {
@@ -174,35 +174,35 @@
        }
        // 如果没有动画名称,使用无动画模式
        if (string.IsNullOrEmpty(skillConfig.SkillMotionName))
        if (string.IsNullOrEmpty(skillSkinConfig.SkillMotionName))
        {
            PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill);
            PlaySkillNoAnim(skillConfig, skillSkinConfig, skillBase, onComplete, isSubSkill);
            return null;
        }
        Spine.Animation targetAnim = FindAnim(skillConfig.SkillMotionName);
        Spine.Animation targetAnim = FindAnim(skillSkinConfig.SkillMotionName);
        if (targetAnim == null)
        {
            skillBase.ForceFinished();
            return null;
        }
        return ExecuteSkillAnim(skillConfig, skillBase, onComplete, targetAnim, true, isSubSkill);
        return ExecuteSkillAnim(skillConfig, skillSkinConfig, skillBase, onComplete, targetAnim, true, isSubSkill);
    }
    private Spine.TrackEntry ExecuteSkillAnim(SkillConfig skillConfig, SkillBase skillBase, Action onComplete,
    private Spine.TrackEntry ExecuteSkillAnim(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, Action onComplete,
        Spine.Animation targetAnim, bool hasAnim, bool isSubSkill)
    {
        int loopCount = skillConfig.LoopCount;
        int loopCount = skillSkinConfig.LoopCount;
        //  前摇
        int startupFrames = skillConfig.StartupFrames;
        int startupFrames = skillSkinConfig.StartupFrames;
        //  中摇
        int[] activeFrames = skillConfig.ActiveFrames ?? new int[0];
        int[] activeFrames = skillSkinConfig.ActiveFrames ?? new int[0];
        int frameCount = activeFrames.Length;
        //  后摇
        float recoveryFrame = skillConfig.RecoveryFrames;
        float recoveryFrame = skillSkinConfig.RecoveryFrames;
        // 如果前中后摇没有配置 那么默认给一个1 2 3的帧数
        if (startupFrames <= 0 && frameCount == 0 && recoveryFrame <= 0f)
@@ -227,7 +227,7 @@
            {
                // 轨道池耗尽或未初始化,回退到无动画模式
                Debug.LogWarning($"子技能轨道池已满或未初始化,技能{skillConfig.SkillID}使用无动画模式");
                PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill);
                PlaySkillNoAnim(skillConfig, skillSkinConfig, skillBase, onComplete, isSubSkill);
                return null;
            }
        }
@@ -244,7 +244,7 @@
                {
                    if (skillBase != null && !skillBase.IsFinished())
                    {
                        PlaySkillAnimation(skillConfig, skillBase, isSubSkill, onComplete);
                        PlaySkillAnimation(skillConfig, skillSkinConfig, skillBase, isSubSkill, onComplete);
                    }
                });
                return null;
@@ -405,13 +405,13 @@
            }
            // 各阶段回调(原有逻辑)
            if (!beginTriggered && currentFrame >= skillConfig.StartupFrames && currentLoop == 0)
            if (!beginTriggered && currentFrame >= skillSkinConfig.StartupFrames && currentLoop == 0)
            {
                beginTriggered = true;
                skillBase.OnStartSkillFrameEnd();
            }
            if (!middleStarted && currentFrame >= skillConfig.StartupFrames && currentLoop <= loopCount)
            if (!middleStarted && currentFrame >= skillSkinConfig.StartupFrames && currentLoop <= loopCount)
            {
                middleStarted = true;
                skillBase.OnMiddleFrameStart(currentLoop);
@@ -440,12 +440,12 @@
                    {
                        if (hasAnim)
                        {
                            skillTrack.TrackTime = skillConfig.StartupFrames / BattleConst.skillMotionFps;
                            skillTrack.TrackTime = skillSkinConfig.StartupFrames / BattleConst.skillMotionFps;
                        }
                        else
                        {
                            // 为下一 loop 重置 startTime,并且更新 pausedAccumulatedAtStart(以保持基线)
                            startTime = Time.time - (skillConfig.StartupFrames / BattleConst.skillMotionFps);
                            startTime = Time.time - (skillSkinConfig.StartupFrames / BattleConst.skillMotionFps);
                            pausedAccumulatedAtStart = pausedAccumulated;
                        }
                    }
@@ -538,8 +538,8 @@
        return targetAnim;
    }
    private void PlaySkillNoAnim(SkillConfig skillConfig, SkillBase skillBase, Action onComplete, bool isSubSkill) =>
        ExecuteSkillAnim(skillConfig, skillBase, onComplete, null, false, isSubSkill);
    private void PlaySkillNoAnim(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, Action onComplete, bool isSubSkill) =>
        ExecuteSkillAnim(skillConfig, skillSkinConfig, skillBase, onComplete, null, false, isSubSkill);
    protected virtual void SetupAnimationHandlers()
    {
@@ -748,9 +748,9 @@
        }
    }
    public bool CanCastSkill(SkillConfig skillConfig)
    public bool CanCastSkill(SkillSkinConfig skillSkinConfig)
    {
        return !playingSkillWithAnim || string.IsNullOrEmpty(skillConfig.SkillMotionName);
        return !playingSkillWithAnim || string.IsNullOrEmpty(skillSkinConfig.SkillMotionName);
    }
    public bool CanStartDeath()