229 lines
7.4 KiB
C#
229 lines
7.4 KiB
C#
using AOT.PostProcess.BlackArea;
|
|
using cfg.BuffCfg;
|
|
using Cysharp.Threading.Tasks;
|
|
using Gameplay.Area;
|
|
using Gameplay.Character;
|
|
using Gameplay.Common;
|
|
using Gameplay.Effect;
|
|
using Gameplay.Performance;
|
|
using Gameplay.Pool;
|
|
using Gameplay.Unit;
|
|
using LTGame;
|
|
using UnityEngine;
|
|
|
|
namespace Gameplay.Vehicle
|
|
{
|
|
public class BatteryStateShoot : BaseBaterryState
|
|
{
|
|
|
|
private float _shootTime;
|
|
private int _fireCount;
|
|
|
|
public BatteryStateShoot(BaseBattery owner) : base(owner, EBatteryState.Shoot)
|
|
{
|
|
|
|
}
|
|
|
|
protected override void _OnEnter(NBaseState exitState,
|
|
object param)
|
|
{
|
|
base._OnEnter(exitState, param);
|
|
|
|
if (exitState != null && exitState is BatteryStateShoot)
|
|
{
|
|
// 自状态循环
|
|
}
|
|
else
|
|
{
|
|
_fireCount = 0;
|
|
}
|
|
|
|
_shootTime = owner.owner.fightData.shootCd;
|
|
|
|
if (owner.rawAnim != null)
|
|
{
|
|
owner.rawAnim.Play("attack", 0, 0);
|
|
}
|
|
|
|
_DoFire();
|
|
}
|
|
|
|
protected override void _OnRunning()
|
|
{
|
|
base._OnRunning();
|
|
|
|
if (owner.owner.statusData.isPretend)
|
|
{
|
|
// 该状态下不可攻击
|
|
isFinished = true;
|
|
nextState = EBatteryState.Idle;
|
|
return;
|
|
}
|
|
|
|
owner.RotateTower(owner.lockEnemy, deltaTime);
|
|
|
|
if (passTime >= _shootTime)
|
|
{
|
|
isFinished = true;
|
|
_CheckEndState();
|
|
}
|
|
}
|
|
|
|
private void _CheckEndState()
|
|
{
|
|
if (owner.remainBulletCount <= 0)
|
|
{
|
|
nextState = EBatteryState.Reload;
|
|
return;
|
|
}
|
|
|
|
if (_fireCount >= owner.owner.fightData.attackLoopCount)
|
|
{
|
|
nextState = EBatteryState.AttackEnd;
|
|
return;
|
|
}
|
|
|
|
nextState = EBatteryState.Idle;
|
|
}
|
|
|
|
private void _DoFire()
|
|
{
|
|
_fireCount++;
|
|
|
|
if (owner.owner.controlData.targetEnemy == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var distanceToTarget = AreaManager.instance.GetDistance(owner.owner.transData.cellIndex,
|
|
owner.owner.controlData.targetEnemy.transData.cellIndex);
|
|
var attackRate = owner.owner.fightData.GetAttackRate(distanceToTarget);
|
|
var randomRate = Random.Range(0f, 1f);
|
|
|
|
_EmitBullet(owner.lockEnemy, randomRate > attackRate);
|
|
}
|
|
|
|
private void _EmitBullet(GameUnit targetEnemy, bool isMiss)
|
|
{
|
|
|
|
if (owner.owner.commonData.troopId != ETroopsId.Self)
|
|
{
|
|
BlackAreaManager.instance.LightUpCell(owner.owner.transData.cellIndex,
|
|
CodeDefine.Fight.SHOOT_LIGHT_UP_TIME);
|
|
}
|
|
|
|
_ShowFireEffects(targetEnemy, isMiss);
|
|
|
|
_PlayFireAudio();
|
|
|
|
if (!isMiss)
|
|
{
|
|
owner.owner.NormalShoot(targetEnemy);
|
|
}
|
|
|
|
if (!owner.owner.buffManager.CheckHasBuffType(EBuffType.NoCostBullet))
|
|
{
|
|
owner.remainBulletCount--;
|
|
}
|
|
}
|
|
|
|
private void _PlayFireAudio()
|
|
{
|
|
var weaponConfig = owner.rawConfig;
|
|
var fireAudioIds = weaponConfig.FireAudioId;
|
|
if (fireAudioIds.Count <= 0) return;
|
|
var fireAudioId = fireAudioIds[Random.Range(0, fireAudioIds.Count)];
|
|
AudioManager.Instance.PlayAudio(fireAudioId, owner.fireTrans.position);
|
|
}
|
|
|
|
private void _ShowFireEffects(GameUnit targetEnemy, bool isMiss)
|
|
{
|
|
var rawWeaponConfig = owner.rawConfig;
|
|
var fireTrans = owner.fireTrans;
|
|
var fireEffectId = rawWeaponConfig.FireEffectId;
|
|
if (fireEffectId > 0)
|
|
{
|
|
var rot = fireTrans.rotation;
|
|
EffectManager.instance.PlayEffectById(fireEffectId, fireTrans.position, rot, fireTrans);
|
|
}
|
|
|
|
var groundEffectId = GLConfig.Inst.data.GroundFireEffectId;
|
|
if (groundEffectId > 0)
|
|
{
|
|
var firePos = fireTrans.position;
|
|
firePos.y = 0.1f;
|
|
EffectManager.instance.PlayEffectById(groundEffectId, firePos);
|
|
}
|
|
|
|
var lineEffectId = rawWeaponConfig.FlyEffectId;
|
|
if (lineEffectId > 0 && PerformanceManager.instance.data.enableBulletTail)
|
|
{
|
|
if (targetEnemy == null || targetEnemy.Node == null || targetEnemy.Node.GameObject == null) return;
|
|
var enemyPos = targetEnemy.Node.GameObject.transform.position;
|
|
if (isMiss)
|
|
{
|
|
var groundPos = enemyPos;
|
|
var randomOffset = Random.Range(0.5f, 0.8f);
|
|
var randomAngle = Random.Range(0, 360);
|
|
var offsetX = Mathf.Cos(randomAngle) * randomOffset;
|
|
var offsetZ = Mathf.Sin(randomAngle) * randomOffset;
|
|
groundPos.x += offsetX;
|
|
groundPos.z += offsetZ;
|
|
|
|
_EmitMissLine(fireTrans, groundPos, rawWeaponConfig.BulletFlySpeed);
|
|
}
|
|
else
|
|
{
|
|
_EmitLine(fireTrans, targetEnemy.Node.GameObject.transform, rawWeaponConfig.BulletFlySpeed);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private void _PlayHitGroundEffect(Vector3 groundPos, int hitEffectId)
|
|
{
|
|
EffectManager.instance.PlayEffectById(hitEffectId, groundPos);
|
|
}
|
|
|
|
private async void _EmitMissLine(Transform start, Vector3 groundPos, float flySpeed)
|
|
{
|
|
var startPos = start.position;
|
|
|
|
var toEnd = groundPos - startPos;
|
|
var angle = Vector3.SignedAngle(Vector3.forward, toEnd, Vector3.up);
|
|
|
|
var effect = EffectManager.instance.PlayEffectById(owner.rawConfig.FlyEffectId, startPos, Quaternion.Euler(0, angle, 0));
|
|
var totalDistance = toEnd.magnitude;
|
|
var flyLogic = ObjPoolManager.instance.Get<BulletFlyLogic>();
|
|
var flyTime = totalDistance / flySpeed;
|
|
flyLogic.Ctor(startPos, groundPos, flyTime);
|
|
effect.AddLogic(flyLogic);
|
|
|
|
await UniTask.WaitForSeconds(flyTime);
|
|
|
|
_PlayHitGroundEffect(groundPos, owner.rawConfig.MissHitGroundEffectId);
|
|
|
|
}
|
|
|
|
private void _EmitLine(Transform start,
|
|
Transform end,
|
|
float flySpeed)
|
|
{
|
|
var rawWeaponConfig = owner.rawConfig;
|
|
// line.effect.transform.LookAt(end, Vector3.up);
|
|
var endPos = end.position;
|
|
var startPos = start.position;
|
|
endPos.y = startPos.y * 0.5f;
|
|
var toEnd = endPos - startPos;
|
|
var angle = Vector3.SignedAngle(Vector3.forward, toEnd, Vector3.up);
|
|
|
|
var effect = EffectManager.instance.PlayEffectById(rawWeaponConfig.FlyEffectId, startPos, Quaternion.Euler(0, angle, 0));
|
|
var totalDistance = toEnd.magnitude;
|
|
var flyLogic = ObjPoolManager.instance.Get<BulletFlyLogic>();
|
|
flyLogic.Ctor(startPos, endPos, totalDistance / flySpeed);
|
|
effect.AddLogic(flyLogic);
|
|
}
|
|
|
|
}
|
|
}
|