hch
2025-09-04 62188b271cce5e3aec5ca40d58c30f08643e2f60
Main/System/Battle/SkillEffect/BulletSkillEffect.cs
@@ -11,91 +11,222 @@
    // protected BattleObject caster;
    // protected List<BattleObject> targets; // 目标列表
    public BulletSkillEffect(SkillConfig _skillConfig, BattleObject _caster, H0604_tagUseSkillAttack _tagUseSkillAttack)
    protected List<BulletCurve> bulletCurves = new List<BulletCurve>();
    public BulletSkillEffect(SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack)
        : base(_skillConfig, _caster, _tagUseSkillAttack)
    {
    }
    public override void Play(Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit)
    public override void OnMiddleFrameStart(int times)
    {
        // Caster, //在施法者上
        // Target, //在目标上
        // AlliesCenter,// 在友方中心
        // EnemiesCenter,// 在敌方中心
        Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> onHitFormation = (_hitIndex, _hurtList) =>
        base.OnMiddleFrameStart(times);
        //  弹射 另外的做法了
        if (skillConfig.effectType == SkillEffectType.Bullet && skillConfig.BulletPath == 4)
        {
            _onHit?.Invoke(_hitIndex, tagUseSkillAttack.HurtList.ToList());
        };
        if (skillConfig.effectAnchor == SkillEffectAnchor.Caster)
        {
            // 不可能子弹射向自己吧
            Debug.LogError("子弹技能特效不能锚定在施法者上 skillConfig.effectAnchor");
            _onHit?.Invoke(0, default);
        }
        else if (skillConfig.effectAnchor == SkillEffectAnchor.Target)
        {
            if (tagUseSkillAttack == null || tagUseSkillAttack.HurtList.Length <= 0)
            var hurt = tagUseSkillAttack.HurtList[0];
            BattleObject targetObject = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
            if (targetObject == null)
            {
                Debug.LogError("子弹技能特效没有目标 tagUseSkillAttack.HurtList.Length <= 0");
                _onHit?.Invoke(0, default);
                Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
                return;
            }
            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;
                }
                ShotToTarget(target.heroGo.transform as RectTransform, (index, list) => _onHit(0, new List<H0604_tagUseSkillAttack.tagSkillHurtObj>() { hurt }));
            }
            ShotToTarget(targetObject);
        }
        else if (skillConfig.effectAnchor == SkillEffectAnchor.AlliesCenter)
        {
            ShotToTarget(caster.battleField.GetTeamNode(caster.Camp), onHitFormation);
        }
        else if (skillConfig.effectAnchor == SkillEffectAnchor.EnemiesCenter)
        {
            ShotToTarget(caster.battleField.GetTeamNode(caster.Camp == BattleCamp.Blue ? BattleCamp.Red : BattleCamp.Blue), onHitFormation);
        }
        //  普通的做法 区分打向阵营或者打向个体
        else
        {
            Debug.LogError("未知的技能特效锚点类型: " + skillConfig.effectAnchor);
            //  区分散射跟范围攻击
            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);
                }
            }
            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) =>
                {
                    onHit?.Invoke(_hitIndex, tagUseSkillAttack.HurtList.ToList());
                };
                if (skillConfig.TagCount >= 6)
                {
                    ShotToFormation(rectTarget, onHitFormation);
                }
                else
                {
                    ShotToFormationEx(rectTarget, onHitFormation);
                }
            }
        }
    }
    protected void ShotToTarget(RectTransform target, Action<int, List<H0604_tagUseSkillAttack.tagSkillHurtObj>> _onHit)
    private void ShotToFormationEx(RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit)
    {
        EffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.EffectId, caster.effectNode);
        effectPlayer.Play();
        BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.heroRectTrans, caster.Camp);
        RectTransform effectTrans = effectPlayer.transform as RectTransform;
        var tween = BattleUtility.MoveToTarget(effectTrans, target, Vector2.zero, skillConfig.FlyTime, () =>
        var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target, tagUseSkillAttack, (index, hitList) =>
        {
            // 表现子弹飞行到目标位置
            _onHit?.Invoke(0, null);
            // 击中就销毁子弹
            caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer);
            // 播放子弹爆炸特效
            //  击中就销毁子弹
            caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.EffectId, effectPlayer);
            //  播放子弹爆炸特效
            caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.ExplotionEffectId, target).Play();
            BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
            foreach (var hurt in hitList)
            {
                BattleObject targetObj = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                if (targetObj == null)
                {
                    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);
            }
            // 表现子弹飞行到目标位置
            _onHit?.Invoke(index, hitList);
            isFinish = true;
        });
        caster.battleField.battleTweenMgr.OnPlayTween(tween);
        bulletCurves.Add(bulletCurve);
    }
    protected void ShotToFormation(RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit)
    {
        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) =>
        {
            // 击中就销毁子弹
            caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer);
            // 播放子弹爆炸特效
            BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
            //  首先是目标身上爆炸
            PlayExplosionEffect(skillConfig.ExplosionEffectId, target, battleCamp);
            PlayExplosionEffect(skillConfig.ExplosionEffect2, target, battleCamp);
            foreach (var hurt in hitList)
            {
                BattleObject targetObj = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                if (targetObj == null)
                {
                    Debug.LogError("目标为空 target == null ObjId : " + hurt.ObjID);
                    continue;
                }
                PlayExplosionEffect(skillConfig.ExplosionEffectId, targetObj.heroGo.transform, targetObj.Camp);
            }
            // 表现子弹飞行到目标位置
            _onHit?.Invoke(index, hitList);
            isFinish = true;
        });
        bulletCurves.Add(bulletCurve);
    }
    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) =>
        {
            foreach (var hurt in hitList)
            {
                BattleObject targetObj = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID);
                if (targetObj == null)
                {
                    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);
            }
            // 表现子弹飞行到目标位置
            onHit?.Invoke(index, hitList);
            // 击中就销毁子弹
            caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer);
            // 播放子弹爆炸特效
            isFinish = true;
        });
        bulletCurves.Add(bulletCurve);
    }
    protected void PlayExplosionEffect(int effectId, Transform parent, BattleCamp camp)
    {
        if (effectId <= 0)
            return;
        var effect = caster.battleField.battleEffectMgr.PlayEffect(0, effectId, parent, camp);
        if (effect != null)
        {
            effect.transform.localRotation = parent.localRotation;
            if (effect.transform.localScale.x < 0f)
            {
                effect.transform.localRotation *= Quaternion.Euler(0, 180, 0);
            }
        }
    }
    public override void Run()
    {
        foreach (var bulletCurve in bulletCurves)
        {
            if (!bulletCurve.IsFinished)
                bulletCurve.Run();
        }
    }
    public override bool IsFinished()
    {
        bool isCurveFinish = false;
        foreach (var bulletCurve in bulletCurves)
        {
            isCurveFinish |= bulletCurve.IsFinished;
        }
        return isCurveFinish && isFinish;
    }
}