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; } _EmitBullet(owner.lockEnemy); } private void _EmitBullet(GameUnit targetEnemy) { if (owner.owner.commonData.troopId != ETroopsId.Self) { BlackAreaManager.instance.LightUpCell(owner.owner.transData.cellIndex, CodeDefine.Fight.SHOOT_LIGHT_UP_TIME); } _PlayFireAudio(); _ShowFireEffects(targetEnemy); 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) { 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); } } 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(); 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(); flyLogic.Ctor(startPos, endPos, totalDistance / flySpeed); effect.AddLogic(flyLogic); } } }