using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using Cysharp.Threading.Tasks;
|
using DG.Tweening;
|
using UnityEngine;
|
|
public class BulletSkillEffect : SkillEffect
|
{
|
// protected SkillConfig skillConfig;
|
// protected BattleObject caster;
|
// protected List<BattleObject> targets; // 目标列表
|
|
protected List<BulletCurve> bulletCurves = new List<BulletCurve>();
|
|
|
public BulletSkillEffect(SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack)
|
: base(_skillConfig, _caster, _tagUseSkillAttack)
|
{
|
|
}
|
|
|
public override void OnMiddleFrameEnd(int times, int index)
|
{
|
base.OnMiddleFrameEnd(times, index);
|
// 弹射 另外的做法了
|
if (skillConfig.effectType == SkillEffectType.Bullet && skillConfig.BulletPath == 4)
|
{
|
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, index);
|
}
|
// 普通的做法 区分打向阵营或者打向个体
|
else
|
{
|
// 区分散射跟范围攻击
|
if (skillConfig.Scattering == 1)
|
{
|
// 散射
|
ShotEachTargets(index);
|
}
|
else
|
{
|
switch (skillConfig.TagAim)
|
{
|
case 0:
|
AllAreaShoting(index);
|
break;
|
case 1:
|
OneTargetShoting(index);
|
break;
|
case 2:
|
FrontRowShoting(index);
|
break;
|
case 3:
|
BackRowShoting(index);
|
break;
|
case 4:
|
VerticalRowShoting(index);
|
break;
|
case 5:
|
SelfShoting(index);
|
break;
|
default:
|
Debug.LogError("子弹特效没有配置正确的TagAim,强制结束子弹特效 TagAim: " + skillConfig.TagAim);
|
ForceFinished();
|
break;
|
}
|
}
|
}
|
}
|
|
// 0 全部范围:
|
private void AllAreaShoting(int index)
|
{
|
if (skillConfig.TagCount == 0 || skillConfig.TagCount >= 6)
|
{
|
// 若TagCount目标个数为0或6,根据TagFriendly敌我配置,代表作用于敌方全体或我方全体,此时主目标为敌我站位中的2号位置
|
BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
|
ShotToIndex(battleCamp, 1, index);
|
}
|
else
|
{
|
// 若TagCount目标个数为1~5个,代表随机作用于敌方或我方x个武将,此时所有被随机到的对象都为主目标(施法位置会用客户端配置)
|
ShotEachTargets(index);
|
}
|
}
|
|
// 1 对位:
|
private void OneTargetShoting(int index)
|
{
|
// 默认只选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, index);
|
}
|
|
// 2 前排:
|
private void FrontRowShoting(int index)
|
{
|
// 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(index);
|
}
|
else
|
{
|
int targetIndex = int.MaxValue;
|
int minimumIndex = int.MaxValue;
|
|
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;
|
}
|
|
minimumIndex = Mathf.Min(target.teamHero.positionNum, minimumIndex);
|
|
if (target.Camp == battleCamp && target.teamHero.positionNum < 3)
|
{
|
targetIndex = 1;
|
break;
|
}
|
}
|
|
if (targetIndex == int.MaxValue)
|
{
|
targetIndex = (minimumIndex >= 3) ? 4 : 1;
|
}
|
else
|
{
|
targetIndex = 1;
|
}
|
|
ShotToIndex(battleCamp, targetIndex, index);
|
}
|
|
}
|
|
private void ShotToIndex(BattleCamp camp, int targetIndex, int bulletIndex)
|
{
|
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, targetTransform, tagUseSkillAttack, bulletIndex, (index, hitList) =>
|
{
|
if (isFinish)
|
return;
|
// 击中就销毁子弹
|
caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer);
|
// 播放子弹爆炸特效
|
|
BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
|
// 首先是目标身上爆炸
|
PlayExplosionEffect(skillConfig.ExplosionEffectId, targetTransform, caster.Camp);
|
PlayExplosionEffect(skillConfig.ExplosionEffect2, targetTransform, caster.Camp);
|
|
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.ExplosionEffect3, targetObj.heroGo.transform, caster.Camp);
|
}
|
|
// 表现子弹飞行到目标位置
|
onHit?.Invoke(index, hitList);
|
|
isFinish = true;
|
});
|
|
bulletCurves.Add(bulletCurve);
|
}
|
|
// 3 后排:
|
private void BackRowShoting(int index)
|
{
|
// 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(index);
|
}
|
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, index);
|
}
|
}
|
|
// 4 纵排:
|
private void VerticalRowShoting(int index)
|
{
|
// 纵排分别为1、4,2、5,3、6,三组纵排,按对位规则选择,默认1号、2号或3号为主目标,前排1、2、3号位置全部死完后,4号、5号或6号为主目标
|
BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp();
|
// 攻击mininumIndex目标
|
int minimumIndex = int.MaxValue;
|
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;
|
}
|
|
minimumIndex = Mathf.Min(target.teamHero.positionNum, minimumIndex);
|
}
|
|
if (minimumIndex != int.MaxValue)
|
{
|
ShotToIndex(battleCamp, minimumIndex, index);
|
}
|
else
|
{
|
Debug.LogError("纵排攻击没有目标 强制结束子弹特效");
|
ForceFinished();
|
}
|
|
|
}
|
|
// 5 自己:
|
private void SelfShoting(int index)
|
{
|
// 默认只选自己,自己为主目标
|
ShotToIndex(caster.Camp, caster.teamHero.positionNum, index);
|
}
|
|
protected void ShotToTarget(BattleObject target, int bulletIndex)
|
{
|
BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.heroRectTrans, caster.Camp);
|
|
var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.heroRectTrans, tagUseSkillAttack, bulletIndex, (index, hitList) =>
|
{
|
if (isFinish)
|
return;
|
|
|
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, caster.Camp);
|
PlayExplosionEffect(skillConfig.ExplosionEffect2, targetObj.heroGo.transform, caster.Camp);
|
PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.heroGo.transform, caster.Camp);
|
}
|
|
// 表现子弹飞行到目标位置
|
onHit?.Invoke(index, hitList);
|
// 击中就销毁子弹
|
caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer);
|
|
if (bulletIndex >= skillConfig.ActiveFrames.Length - 1)
|
{
|
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);
|
}
|
}
|
}
|
|
private void ShotEachTargets(int index)
|
{
|
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, index);
|
}
|
}
|
|
|
public override void Run()
|
{
|
foreach (var bulletCurve in bulletCurves)
|
{
|
if (!bulletCurve.IsFinished)
|
bulletCurve.Run();
|
}
|
}
|
|
public override void ForceFinished()
|
{
|
base.ForceFinished();
|
foreach (var bulletCurve in bulletCurves)
|
{
|
bulletCurve.ForceFinish();
|
}
|
}
|
|
public override bool IsFinished()
|
{
|
bool isCurveFinish = false;
|
|
foreach (var bulletCurve in bulletCurves)
|
{
|
isCurveFinish |= bulletCurve.IsFinished;
|
}
|
|
return isCurveFinish && base.IsFinished();
|
}
|
}
|