yyl
2025-10-31 1a30a307bc79d887139b4b90f40b274e344d2285
Main/System/Battle/Motion/MotionBase.cs
@@ -23,6 +23,7 @@
    protected Spine.Skeleton skeleton;
    protected float defaultMixDuration = 0f;
    private Spine.TrackEntry currentTrack;
    private Dictionary<int, Spine.TrackEntry> activeSkillTracks = new Dictionary<int, Spine.TrackEntry>(); // 改为字典:trackIndex -> TrackEntry
    private SkeletonIllusionShadow illusionShadow;
    private bool playingSkillAnim = false;
@@ -61,6 +62,7 @@
    public virtual void Release()
    {
        trackEntryCallbacks.Clear();
        activeSkillTracks.Clear();
        if (animState != null)
        {
            animState.Complete -= OnAnimationComplete;
@@ -107,7 +109,8 @@
            return null;
        }
        if (string.IsNullOrEmpty(skillConfig.SkillMotionName))
        // 子技能强制使用无动画模式,或者如果没有动画名称
        if (isSubSkill || string.IsNullOrEmpty(skillConfig.SkillMotionName))
        {
            PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill);
            return null;
@@ -133,11 +136,23 @@
        int frameCount = activeFrames.Length;
        float recoveryFrame = skillConfig.RecoveryFrames;
        // 主技能用 track 0,子技能用 track 1
        int trackIndex = isSubSkill ? 1 : 0;
        Spine.TrackEntry skillTrack = null;
        if (hasAnim)
        {
            skillTrack = animState.SetAnimation(0, targetAnim, false);
            skillTrack = animState.SetAnimation(trackIndex, targetAnim, false);
            if (null == skillTrack || skillConfig.SkillID == 3008020)
            {
                Debug.Break();
            }
            // 只有主技能才更新 currentTrack
            if (!isSubSkill)
            currentTrack = skillTrack;
            activeSkillTracks[trackIndex] = skillTrack;
        }
        
        playingSkillAnim = true;
@@ -149,7 +164,7 @@
        // 新增:记录技能开始时的 pausedAccumulated 基线,用于后续计算该技能自身的暂停时长
        float pausedAccumulatedAtStart = pausedAccumulated;
        // startTime 表示技能“本地逻辑时间”的起点(以 Time.time 为基准)
        // startTime 表示技能"本地逻辑时间"的起点(以 Time.time 为基准)
        float startTime = hasAnim ? 0f : Time.time;
        skillBase.OnSkillStart();
@@ -160,7 +175,16 @@
            if (skillBase.IsFinished())
            {
                // 清理并退出(保证状态一致)
                if (skillTrack != null && activeSkillTracks.ContainsKey(trackIndex))
                {
                    if (activeSkillTracks[trackIndex] == skillTrack)
                        activeSkillTracks.Remove(trackIndex);
                }
                // 只有当没有其他活跃技能时才复位 playingSkillAnim
                if (activeSkillTracks.Count == 0)
                playingSkillAnim = false;
                RemoveAction(frameHandler);
                return;
            }
@@ -173,7 +197,7 @@
            }
            else
            {
                // 使用 pausedAccumulatedAtStart 来计算“这个技能自开始以来的暂停总时长”
                // 使用 pausedAccumulatedAtStart 来计算"这个技能自开始以来的暂停总时长"
                float adjustedTime = Time.time;
                float thisSkillPaused = pausedAccumulated - pausedAccumulatedAtStart;
                if (thisSkillPaused < 0f) thisSkillPaused = 0f; // 保险防护
@@ -186,13 +210,15 @@
            if (hasAnim)
            {
                if (currentTrack != skillTrack)
                // 检查当前轨道是否被新技能覆盖
                if (!activeSkillTracks.ContainsKey(trackIndex) || activeSkillTracks[trackIndex] != skillTrack)
                {
                    Debug.LogError("技能动画被打断,强制结束 " + skillConfig.SkillID);
                    skillBase.ForceFinished();
                    // 清理并确保状态复位
                    RemoveAction(frameHandler);
                    if (activeSkillTracks.Count == 0)
                    playingSkillAnim = false;
                    return;
                }
@@ -203,6 +229,9 @@
                    Debug.LogError("技能动画播放失败,强制结束 " + skillConfig.SkillID);
                    skillBase.ForceFinished();
                    RemoveAction(frameHandler);
                    if (activeSkillTracks.ContainsKey(trackIndex))
                        activeSkillTracks.Remove(trackIndex);
                    if (activeSkillTracks.Count == 0)
                    playingSkillAnim = false;
                    return;
                }
@@ -273,7 +302,15 @@
                {
                    finalEnded = true;
                    // 一定要把 playingSkillAnim 复位(无论是否是子技能),否则可能导致后续动画被拦截
                    // 清理技能轨道
                    if (skillTrack != null && activeSkillTracks.ContainsKey(trackIndex))
                    {
                        if (activeSkillTracks[trackIndex] == skillTrack)
                            activeSkillTracks.Remove(trackIndex);
                    }
                    // 只有当没有其他活跃技能时才复位 playingSkillAnim
                    if (activeSkillTracks.Count == 0)
                    playingSkillAnim = false;
                    RemoveAction(frameHandler);
@@ -402,6 +439,7 @@
    {
        trackEntryCallbacks.Clear();
        runningActions.Clear();
        activeSkillTracks.Clear();
        playingSkillAnim = false;
        PlayAnimation(MotionName.idle, true);
    }