lcy
2026-02-04 e80cb92bf4b84cab4d87bf3a23bbf21da311cd03
Main/System/Battle/Skill/SkillBase.cs
@@ -35,7 +35,7 @@
    public bool isPlay = false;
    //  父RecordAction(SkillRecordAction),用于子技能建立父子关系
    protected RecordAction parentRecordAction;
    protected SkillRecordAction ownRecordAction;
    
    //  技能动画是否播放完成(针对有动画的技能)
    protected bool isMotionCompleted = false;
@@ -73,9 +73,9 @@
    }
    //  设置父RecordAction
    public void SetParentRecordAction(RecordAction recordAction)
    public void SetOwnRecordAction(SkillRecordAction recordAction)
    {
        parentRecordAction = recordAction;
        ownRecordAction = recordAction;
    }
#if UNITY_EDITOR
@@ -92,7 +92,7 @@
            var Hurt = tagUseSkillAttack.HurtList[i];
            BattleObject battleObject = caster.battleField.battleObjMgr.GetBattleObject((int)Hurt.ObjID);
            
            string targetName = battleObject != null ? battleObject.teamHero.name : "Unknown";
            string targetName = battleObject != null ? battleObject.GetName() : "Unknown";
            long hurtHp = GeneralDefine.GetFactValue(Hurt.HurtHP, Hurt.HurtHPEx);
            long curHp = GeneralDefine.GetFactValue(Hurt.CurHP, Hurt.CurHPEx);
            
@@ -125,7 +125,7 @@
                var HurtEx = tagUseSkillAttack.HurtListEx[i];
                BattleObject battleObject = caster.battleField.battleObjMgr.GetBattleObject((int)HurtEx.ObjID);
                
                string targetName = battleObject != null ? battleObject.teamHero.name : "Unknown";
                string targetName = battleObject != null ? battleObject.GetName() : "Unknown";
                long hurtHp = GeneralDefine.GetFactValue(HurtEx.HurtHP, HurtEx.HurtHPEx);
                long curHp = GeneralDefine.GetFactValue(HurtEx.CurHP, HurtEx.CurHPEx);
                
@@ -225,13 +225,13 @@
            if (change)
            {
                MoveSpeed = 1125f;
                caster.motionBase.ShowIllusionShadow(true, color);
                caster.ShowIllusionShadow(true, color);
            }
        }
        else
        {
            MoveSpeed = 750f;
            caster.motionBase.ShowIllusionShadow(false);
            caster.ShowIllusionShadow(false);
        }
    }
@@ -240,7 +240,13 @@
    {
        // 广播技能释放事件
        string guid = battleField.guid;
        TeamHero teamHero = caster.teamHero;
        // 获取释放者数据:Hero 传递 teamHero,Mingge 传递 null(因为事件监听器只处理 Hero 数据)
        TeamHero teamHero = null;
        if (caster is HeroBattleObject heroBattleObject)
        {
            teamHero = heroBattleObject.teamHero;
        }
        // 命格释放技能时 teamHero 为 null,监听器会正确处理(已有 null 检查)
        EventBroadcast.Instance.Broadcast<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, guid, skillConfig, teamHero);
        if (skillConfig.SkinllSFX1 != 0)
@@ -303,7 +309,7 @@
    {
        if (hintConfig != null)
        {
            battleObject.heroInfoBar.ShowTips(((char)hintConfig.prefix).ToString(), true, false, 1.25f);
            battleObject.ShowTips(((char)hintConfig.prefix).ToString(), true, false, 1.25f);
        }
    }
@@ -327,7 +333,7 @@
            else
            {
                // ShadowIllutionCreate(true);
                MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, () =>
                MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.GetPositionNum()), Vector2.zero, () =>
                {
                    // ShadowIllutionCreate(false);
                    OnAttackFinish();
@@ -352,7 +358,7 @@
        ExecuteMoveAndCastSequence(targetTrans, () =>
        {
            RectTransform rectTransform = battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum);
            RectTransform rectTransform = battleField.GetTeamNode(caster.Camp, caster.GetPositionNum());
            // ShadowIllutionCreate(true);
            MoveToTarget(rectTransform, Vector2.zero, () =>
            {
@@ -375,7 +381,7 @@
            else
            {
                // ShadowIllutionCreate(true);
                MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, () =>
                MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.GetPositionNum()), Vector2.zero, () =>
                {
                    // ShadowIllutionCreate(false);
                    OnAttackFinish();
@@ -427,10 +433,10 @@
            return;
        }
        caster.motionBase.PlayAnimation(MotionName.run, true);
        var tweener = BattleUtility.MoveToTarget(caster.heroRectTrans, target, offset, () =>
        caster.PlayAnimation(MotionName.run, true);
        var tweener = BattleUtility.MoveToTarget(caster.GetRectTransform(), target, offset, () =>
        {
            caster.motionBase.PlayAnimation(MotionName.idle, true);
            caster.PlayAnimation(MotionName.idle, true);
            _onComplete?.Invoke();
        }, speed);
        battleField.battleTweenMgr.OnPlayTween(tweener);
@@ -441,9 +447,7 @@
    {
        if (skillConfig.CastDistance < 0)
        {
            Vector3 scale = caster.heroGo.transform.localScale;
            scale.x = Mathf.Abs(scale.x) * forward;
            caster.heroGo.transform.localScale = scale;
            caster.SetFacing(forward);
        }
        _onComplete?.Invoke();
    }
@@ -453,7 +457,7 @@
    {
        TurnBack(null, 1f);
        OnAllAttackMoveFinished();
        caster.motionBase.PlayAnimation(MotionName.idle, true);
        caster.PlayAnimation(MotionName.idle, true);
    }
    // 所有攻击移动完成后的处理:恢复UI显示状态
@@ -464,7 +468,7 @@
        foreach (BattleObject bo in allList)
        {
            bo.layerMgr.SetFront();
            bo.heroInfoBar.SetActive(true);
            bo.GetHeroInfoBar()?.SetActive(true);
        }
        battleField.battleRootNode.skillMaskNode.SetActive(false);
    }
@@ -472,7 +476,7 @@
    // 执行技能释放动画和逻辑:播放施法动作并提供回调
    protected TrackEntry CastImpl(Action onComplete = null)
    {
        return caster.motionBase.PlaySkillAnimation(skillConfig, this, tagUseSkillAttack.BattleType == 4, onComplete);
        return caster.PlaySkillAnimation(skillConfig, this, tagUseSkillAttack.BattleType == 4, onComplete);
    }
    // 技能开始回调:处理死亡、子技能、技能效果初始化
@@ -513,6 +517,10 @@
                {
                    break;
                }
                if (ssc.SkillType == 8)
                {
                    break;
                }
                SkillRecordAction skillRecordAction = CustomHB426CombinePack.CreateSkillAction(battleField.guid, new List<GameNetPackBasic> { skillPack });
                allSubSkills.Add((skillPack.packUID, skillRecordAction));
                removePackList.Add(pack);
@@ -530,9 +538,20 @@
                {
                    break;
                }
                if (ssc.SkillType == 8)
                {
                    break;
                }
                SkillRecordAction skillRecordAction = combinePack.CreateSkillAction();
                allSubSkills.Add((sp.packUID, skillRecordAction));
                removePackList.Add(pack);
                if (skillRecordAction.useParentRecordPlayer)
                {
                    break;
                }
            }
        }
@@ -546,11 +565,13 @@
        foreach (var (packUID, recordAction) in allSubSkills)
        {
            battleField.recordPlayer.ImmediatelyPlay(recordAction);
            if (recordAction.IsNeedWaiting())
            if (recordAction.useParentRecordPlayer)
            {
                currentWaitingSkill.Add(recordAction);
                ownRecordAction.GetInnerRecordPlayer().PlayRecord(recordAction, ownRecordAction);
            }
            else
            {
                ownRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(recordAction);
            }
        }
    }
@@ -639,7 +660,7 @@
        var highlightSet = new HashSet<BattleObject>(highlightList);
        // 先把施法者的 InfoBar 隐藏(原逻辑保留)
        caster.heroInfoBar.SetActive(false);
        caster.GetHeroInfoBar()?.SetActive(false);
        foreach (BattleObject bo in allList)
        {
@@ -656,7 +677,7 @@
            }
            // 目标(含 HurtListEx)都应显示 InfoBar
            bo.heroInfoBar.SetActive(isTarget);
            bo.GetHeroInfoBar()?.SetActive(isTarget);
        }
        battleField.battleRootNode.skillMaskNode.SetActive(true);
@@ -666,7 +687,7 @@
    // 命中目标回调:处理所有被命中的目标(包括主目标、弹射目标、溅射目标)
    protected virtual void OnHitTargets(int _hitIndex, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hitList)
    {
        // Debug.LogError($"Skill {skillConfig.SkillID} hit targets _hitIndex: {_hitIndex} hit {string.Join(", ", hitList.Select(h => h.ObjID + ":" + battleField.battleObjMgr.GetBattleObject((int)h.ObjID)?.teamHero.name))}");
        // Debug.LogError($"Skill {skillConfig.SkillID} hit targets _hitIndex: {_hitIndex} hit {string.Join(", ", hitList.Select(h => h.ObjID + ":" + battleField.battleObjMgr.GetBattleObject((int)h.ObjID)?.GetName()))}");
        //  造成伤害前先处理血量刷新包
        HandleRefreshHP();
@@ -773,8 +794,8 @@
                        DamageNumConfig hintConfig = DamageNumConfig.Get(BattleConst.BreakArmor);
                        Hint(battleObject, hintConfig);
                        battleField.battleEffectMgr.PlayEffect(battleObject, 
                            BattleConst.BreakArmorEffectID, battleObject.heroRectTrans, battleObject.Camp,
                            battleObject.teamHero.modelScale);
                            BattleConst.BreakArmorEffectID, battleObject.GetRectTransform(), battleObject.Camp,
                            battleObject.GetModelScale());
                    }
                }
                else if ((hurt.AttackTypes & (int)DamageType.Parry) == (int)DamageType.Parry)
@@ -785,8 +806,8 @@
                        DamageNumConfig hintConfig = DamageNumConfig.Get(BattleConst.Parry);
                        Hint(battleObject, hintConfig);
                        battleField.battleEffectMgr.PlayEffect(battleObject, 
                            BattleConst.ParryEffectID, battleObject.heroRectTrans, battleObject.Camp,
                            battleObject.teamHero.modelScale);
                            BattleConst.ParryEffectID, battleObject.GetRectTransform(), battleObject.Camp,
                            battleObject.GetModelScale());
                    }
                }
            }
@@ -814,12 +835,12 @@
#endif
        // 先调用目标受伤
        DeathRecordAction recordAc = target.Hurt(hurtParam, parentRecordAction);
        DeathRecordAction recordAc = target.Hurt(hurtParam, ownRecordAction);
        if (null != recordAc)
        {
            tempDeadPackList.Remove(hurtParam.hurter.hurtObj.ObjID);
            battleField.recordPlayer.ImmediatelyPlay(recordAc, parentRecordAction, true);
            ownRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(recordAc, ownRecordAction, true);
            currentWaitingSkill.Add(recordAc);
        }
        
@@ -874,8 +895,8 @@
        
        BattleDebug.LogError(
            (hurtParam.caster.casterObj.Camp == BattleCamp.Red ? "【红方行动】" : "【蓝方行动】 ") +
            $"攻击者: {hurtParam.caster.casterObj.teamHero.name} (ObjID:{hurtParam.caster.casterObj.ObjID})\n" +
            $"目标: {hurtParam.hurter.hurtObj.teamHero.name} (ObjID:{hurtParam.hurter.hurtObj.ObjID})\n" +
            $"攻击者: {hurtParam.caster.casterObj.GetName()} (ObjID:{hurtParam.caster.casterObj.ObjID})\n" +
            $"目标: {hurtParam.hurter.hurtObj.GetName()} (ObjID:{hurtParam.hurter.hurtObj.ObjID})\n" +
            $"技能: {hurtParam.skillConfig.SkillName} (ID:{hurtParam.skillConfig.SkillID})\n" +
            $"击数: 第{hurtParam.hitIndex + 1}击 / 共{hurtParam.skillConfig.DamageDivide.Length}击" + (isLastHit ? " [最后一击]" : " [中间击]") + "\n" +
            $"\n" +
@@ -909,7 +930,7 @@
            // 【使用 parentRecordAction.innerRecordPlayer】
            // 原因:HP刷新包是技能内部产生的,应该由当前SkillRecordAction的innerRecordPlayer管理
            // 这样可以确保HP刷新与技能的生命周期绑定,ForceFinish时一并处理
            PackageRegeditEx.DistributeToRecordAction(refreshPack, parentRecordAction);
            PackageRegeditEx.DistributeToRecordAction(refreshPack, ownRecordAction);
            packList.Remove(refreshPack);
        }
    }
@@ -975,7 +996,7 @@
            // 【使用 parentRecordAction.innerRecordPlayer】
            // 原因:掉落包是技能效果的一部分,应该由当前SkillRecordAction管理
            // 掉落包的分发与技能完成绑定,确保在技能ForceFinish时正确处理
            PackageRegeditEx.DistributeToRecordAction(_dropPack, parentRecordAction);
            PackageRegeditEx.DistributeToRecordAction(_dropPack, ownRecordAction);
            packList.Remove(_dropPack);
        }
@@ -1005,7 +1026,7 @@
            
            BattleDrops battleDrops = new BattleDrops()
            {
                rectTransform = deadTarget.heroRectTrans,
                rectTransform = deadTarget.GetRectTransform(),
                dropItemPackIndex = itemIndexList,
                expDrops = expAssign[i]
            };
@@ -1233,6 +1254,7 @@
            return false;
        }
        // 检查最终完成状态
        if (isFinished && moveFinished)
        {
@@ -1243,7 +1265,7 @@
            }
            //  如果自己内部的recora action的 inner record player还有没执行完的包 也是返回false
            if (parentRecordAction != null && parentRecordAction.GetInnerRecordPlayer().IsPlaying())
            if (ownRecordAction != null && ownRecordAction.GetInnerRecordPlayer().IsPlaying())
            {
                return false;
            }
@@ -1254,16 +1276,16 @@
                battleField.RemoveCastingSkill(caster.ObjID, this);
                
                //  传递parentRecordAction,让死亡技能等待当前技能完成
                DeathRecordAction recordAction = battleField.OnObjsDead(new List<BattleDeadPack>(tempDeadPackList.Values));
                DeathRecordAction recordAction = battleField.OnObjsDead(new List<BattleDeadPack>(tempDeadPackList.Values), null, ownRecordAction);
                if (null != recordAction)
                {
                    parentRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(recordAction);
                    ownRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(recordAction);
                    tempDeadPackList.Clear();
                    return false;
                }
            }
            return true;
            return !ownRecordAction.GetInnerRecordPlayer().IsPlaying();
        }
        return false;
@@ -1286,8 +1308,9 @@
        RecordAction rc = battleField.OnObjsDead(new List<BattleDeadPack>(tempDeadPackList.Values));
        if (null != rc)
        {
            parentRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(rc);
            ownRecordAction.GetInnerRecordPlayer().ImmediatelyPlay(rc);
        }
        tempDeadPackList.Clear();
        // 1. 强制结束技能效果
        skillEffect?.ForceFinished();
@@ -1304,36 +1327,22 @@
        }
        // 3. 清理 DOTween 动画(防止移动回调在战斗结束后执行)
        if (caster != null && caster.heroRectTrans != null)
        if (caster != null)
        {
            DG.Tweening.DOTween.Kill(caster.heroRectTrans);
            caster.StopMoveAnimation();
        }
        // 4. 重置施法者状态
        if (caster != null)
        {
            // 重置位置到原点
            if (caster.heroRectTrans != null)
            {
                caster.heroRectTrans.anchoredPosition = Vector2.zero;
            }
            caster.ResetPosition();
            
            // 重置朝向
            if (caster.heroGo != null)
            {
                Vector3 scale = caster.heroGo.transform.localScale;
                scale.x = Mathf.Abs(scale.x);
                caster.heroGo.transform.localScale = scale;
            }
            caster.ResetFacing();
            // 取消幻影效果
            caster.motionBase?.ShowIllusionShadow(false);
            // 播放待机动画(如果还活着)
            if (!caster.teamHero.isDead)
            {
                caster.motionBase?.ResetForReborn(false);
            }
            caster.ShowIllusionShadow(false);
        }
        // 5. 恢复 UI 状态
@@ -1346,7 +1355,7 @@
                foreach (BattleObject bo in allList)
                {
                    bo.layerMgr?.SetFront();
                    bo.heroInfoBar?.SetActive(true);
                    bo.GetHeroInfoBar()?.SetActive(true);
                }
            }
            
@@ -1458,11 +1467,20 @@
            if (pack is CustomHB426CombinePack combinePack && combinePack.startTag.Tag.StartsWith("Skill_"))
            {
                BattleDebug.LogError("other skill casting " + combinePack.startTag.Tag);
                var skillRecordAction = combinePack.CreateSkillAction();
                skillRecordAction.fromSkill = this;
                currentWaitingSkill.Add(skillRecordAction);
                parentRecordAction.GetInnerRecordPlayer().PlayRecord(skillRecordAction);
                //  需要给真正parent播的
                if (skillRecordAction.useParentRecordPlayer && skillRecordAction.parentSkillAction != null)
                {
                    skillRecordAction.parentSkillAction.GetInnerRecordPlayer().PlayRecord(skillRecordAction);
                }
                else
                {
                    ownRecordAction.GetInnerRecordPlayer().PlayRecord(skillRecordAction);
                }
                return false;
            }
            else if (IsBuffPack(pack))
@@ -1495,7 +1513,7 @@
                // 【使用 parentRecordAction.innerRecordPlayer】
                // 原因:技能执行过程中的包(Buff、属性刷新等)是技能效果的一部分
                // 应该由SkillRecordAction的innerRecordPlayer管理,确保与技能生命周期一致
                PackageRegeditEx.DistributeToRecordAction(pack, parentRecordAction);
                PackageRegeditEx.DistributeToRecordAction(pack, ownRecordAction);
            }
        }
@@ -1540,7 +1558,11 @@
                BattleObject battleObj = battleField.battleObjMgr.GetBattleObject((int)buffRefresh.ObjID);
                if (battleObj != null)
                {
                    battleObj.buffMgr.RefreshBuff(buffRefresh, true);
                    var buffMgr = battleObj.GetBuffMgr();
                    if (buffMgr != null) // 命格不有 buff 管理器
                    {
                        buffMgr.RefreshBuff(buffRefresh, true);
                    }
                }
            }
            else if (pack is HB429_tagSCBuffDel buffDel)
@@ -1548,7 +1570,11 @@
                BattleObject battleObj = battleField.battleObjMgr.GetBattleObject((int)buffDel.ObjID);
                if (battleObj != null)
                {
                    battleObj.buffMgr.RemoveBuff(buffDel, false);
                    var buffMgr = battleObj.GetBuffMgr();
                    if (buffMgr != null) // 命格不有 buff 管理器
                    {
                        buffMgr.RemoveBuff(buffDel, false);
                    }
                }
            }
        }
@@ -1566,7 +1592,7 @@
            // 【使用 parentRecordAction.innerRecordPlayer】
            // 原因:Buff包是技能效果的核心组成部分,应该由SkillRecordAction管理
            // 即使是强制分发的情况,也要保持在正确的RecordAction上下文中
            PackageRegeditEx.DistributeToRecordAction(pack, parentRecordAction);
            PackageRegeditEx.DistributeToRecordAction(pack, ownRecordAction);
        }
    }