yyl
2025-09-10 6696f835cfba7fd451d7a78342bb56cdc6e2e940
Main/System/Battle/SkillEffect/BulletSkillEffect.cs
@@ -39,93 +39,134 @@
        else
        {
            //  区分散射跟范围攻击
            if (skillConfig.Scattering == 1)
            {
                //  散射
                for (int i = 0; i < tagUseSkillAttack.HurtList.Length; i++)
                {
                    var hurt = tagUseSkillAttack.HurtList[i];
                    BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                    if (target == null)
                    {
                        Debug.LogError("特效目标为空 target == null ObjId : " + hurt.ObjID);
                        continue;
                    }
                    ShotToTarget(target);
                }
                ShotEachTargets();
            }
            else
            {
                //  范围攻击
                //  攻击向关键位置 然后所有人受伤
                int mainTargetIndex = BattleUtility.GetMainTargetPositionNum(caster, tagUseSkillAttack.HurtList.ToList(), skillConfig);
                BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
                RectTransform rectTarget = caster.battleField.GetTeamNode(battleCamp, mainTargetIndex);
                Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHitFormation = (_hitIndex, _hurtList) =>
                switch (skillConfig.TagAim)
                {
                    onHit?.Invoke(_hitIndex, tagUseSkillAttack.HurtList.ToList());
                };
                if (skillConfig.TagCount >= 6)
                {
                    ShotToFormation(rectTarget, onHitFormation);
                }
                else
                {
                    ShotToFormationEx(rectTarget, onHitFormation);
                    case 0:
                        AllAreaShoting();
                        break;
                    case 1:
                        OneTargetShoting();
                        break;
                    case 2:
                        FrontRowShoting();
                        break;
                    case 3:
                        BackRowShoting();
                        break;
                    case 4:
                        VerticalRowShoting();
                        break;
                    case 5:
                        SelfShoting();
                        break;
                }
            }
        }
    }
    private void ShotToFormationEx(RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit)
    // 0   全部范围:
    private void AllAreaShoting()
    {
        BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.heroRectTrans, caster.Camp);
        RectTransform effectTrans = effectPlayer.transform as RectTransform;
        var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target, tagUseSkillAttack, (index, hitList) =>
        if (skillConfig.TagCount == 0 || skillConfig.TagCount >= 6)
        {
            // 击中就销毁子弹
            caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer);
            // 播放子弹爆炸特效
            // 若TagCount目标个数为0或6,根据TagFriendly敌我配置,代表作用于敌方全体或我方全体,此时主目标为敌我站位中的2号位置
            BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
            ShotToIndex(battleCamp, 1);
        }
        else
        {
            // 若TagCount目标个数为1~5个,代表随机作用于敌方或我方x个武将,此时所有被随机到的对象都为主目标(施法位置会用客户端配置)
            ShotEachTargets();
        }
    }
            foreach (var hurt in hitList)
    // 1    对位:
    private void OneTargetShoting()
    {
        // 默认只选1个,对位规则为A1优先打B1,A2优先打B2,A3优先打B3,对位目标死亡时,优先前排,
        // 比如B2已经死亡,那么A2将优先打B1,前排1、2、3号位置全部死亡之后才开始选择后排4、5、6号位置,
        // 对位只可选1个目标,即主目标
        if (tagUseSkillAttack.HurtList.Length > 1)
        {
            Debug.LogError("服务器 对位攻击目标数量错误,应该只有一个目标 技能id" + skillConfig.SkillID);
        }
        var hurt = tagUseSkillAttack.HurtList[0];
        BattleObject targetObject = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
        if (targetObject == null)
        {
            Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
            return;
        }
        ShotToTarget(targetObject);
    }
    // 2    前排:
    private void FrontRowShoting()
    {
        // 1、2、3号位为前排,默认2号位置为主目标,当1、2、3号位置角色全部死亡,前排将替换成后排,5号位置变更为主目标,
        // 若配置TagAffect细分目标,且人数小于3,则所有被选择目标均为主目标(施法位置会用客户端配置)
        // (即前排默认2号位或5号位规则无效,实际作用多少人就是多少个主目标)
        BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
        if (skillConfig.TagAffect != 0 && skillConfig.TagAffect != 3 && skillConfig.TagCount < 3)
        {
            ShotEachTargets();
        }
        else
        {
            int targetIndex = int.MaxValue;
            int minimumIndex = int.MaxValue;
            foreach (var hurt in tagUseSkillAttack.HurtList)
            {
                BattleObject targetObj = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                if (targetObj == null)
                BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                if (target == null)
                {
                    Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
                    Debug.LogError("特效目标为空 target == null ObjId : " + hurt.ObjID);
                    continue;
                }
                PlayExplosionEffect(skillConfig.ExplosionEffectId, targetObj.heroGo.transform, targetObj.Camp);
                PlayExplosionEffect(skillConfig.ExplosionEffect2, targetObj.heroGo.transform, targetObj.Camp);
                PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.heroGo.transform, targetObj.Camp);
                minimumIndex = Mathf.Min(target.teamHero.positionNum, minimumIndex);
                if (target.Camp == battleCamp && target.teamHero.positionNum < 3)
                {
                    targetIndex = 1;
                    break;
                }
            }
            // 表现子弹飞行到目标位置
            _onHit?.Invoke(index, hitList);
            isFinish = true;
        });
            if (targetIndex == int.MaxValue)
            {
                targetIndex = (minimumIndex >= 3) ? 4 : 1;
            }
            else
            {
                targetIndex = 1;
            }
        bulletCurves.Add(bulletCurve);
            ShotToIndex(battleCamp, targetIndex);
        }
    }
    protected void ShotToFormation(RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit)
    private void ShotToIndex(BattleCamp camp, int targetIndex)
    {
        RectTransform targetTransform = caster.battleField.GetTeamNode(camp, targetIndex);
        BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.heroRectTrans, caster.Camp);
        RectTransform effectTrans = effectPlayer.transform as RectTransform;
        var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target, tagUseSkillAttack, (index, hitList) =>
        var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, targetTransform, tagUseSkillAttack, (index, hitList) =>
        {
            if (isFinish)
                return;
@@ -135,8 +176,8 @@
            BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
            //  首先是目标身上爆炸
            PlayExplosionEffect(skillConfig.ExplosionEffectId, target, battleCamp);
            PlayExplosionEffect(skillConfig.ExplosionEffect2, target, battleCamp);
            PlayExplosionEffect(skillConfig.ExplosionEffectId, targetTransform, battleCamp);
            PlayExplosionEffect(skillConfig.ExplosionEffect2, targetTransform, battleCamp);
            foreach (var hurt in hitList)
            {
@@ -147,23 +188,86 @@
                    continue;
                }
                PlayExplosionEffect(skillConfig.ExplosionEffectId, targetObj.heroGo.transform, targetObj.Camp);
                PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.heroGo.transform, targetObj.Camp);
            }
            // 表现子弹飞行到目标位置
            _onHit?.Invoke(index, hitList);
            onHit?.Invoke(index, hitList);
            isFinish = true;
        });
        bulletCurves.Add(bulletCurve);
    }
    // 3    后排:
    private void BackRowShoting()
    {
        // 4、5、6号位为后排,默认5号位置为主目标,当4、5、6号位置角色全部死亡,后排排将替换成前排,2号位置变更为主目标,
        // 若配置TagAffect细分目标,且人数小于3,则所有被选择目标均为主目标(施法位置会用客户端配置)
        // (即前排默认2号位或5号位规则无效,实际作用多少人就是多少个主目标)
        BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
        if (skillConfig.TagAffect != 0 && skillConfig.TagAffect != 3 && skillConfig.TagCount < 3)
        {
            ShotEachTargets();
        }
        else
        {
            int targetIndex = int.MaxValue;
            int maxinumIndex = int.MinValue;
            foreach (var hurt in tagUseSkillAttack.HurtList)
            {
                BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                if (target == null)
                {
                    Debug.LogError("特效目标为空 target == null ObjId : " + hurt.ObjID);
                    continue;
                }
                if (target.Camp == battleCamp && target.teamHero.positionNum > 3)
                {
                    targetIndex = 4;
                    break;
                }
                maxinumIndex = Mathf.Max(target.teamHero.positionNum, maxinumIndex);
            }
            if (targetIndex == int.MaxValue)
            {
                targetIndex = (maxinumIndex < 3) ? 1 : 4;
            }
            else
            {
                targetIndex = 4;
            }
            ShotToIndex(battleCamp, targetIndex);
        }
    }
    // 4    纵排:
    private void VerticalRowShoting()
    {
        // 纵排分别为1、4,2、5,3、6,三组纵排,按对位规则选择,默认1号、2号或3号为主目标,前排1、2、3号位置全部死完后,4号、5号或6号为主目标
        ShotEachTargets();
    }
    // 5    自己:
    private void SelfShoting()
    {
        // 默认只选自己,自己为主目标
        ShotToIndex(caster.Camp, caster.teamHero.positionNum);
    }
    protected void ShotToTarget(BattleObject target)
    {
        BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.heroRectTrans, caster.Camp);
        var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.heroRectTrans, tagUseSkillAttack, (index, hitList) =>
        {
@@ -213,6 +317,20 @@
        }
    }
    private void ShotEachTargets()
    {
        for (int i = 0; i < tagUseSkillAttack.HurtList.Length; i++)
        {
            var hurt = tagUseSkillAttack.HurtList[i];
            BattleObject target = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
            if (target == null)
            {
                Debug.LogError("特效目标为空 target == null ObjId : " + hurt.ObjID);
                continue;
            }
            ShotToTarget(target);
        }
    }
    public override void Run()