using Cysharp.Threading.Tasks; 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; public BatteryStateShoot(BaseBattery owner) : base(owner, EBatteryState.Shoot) { } protected override void _OnEnter(NBaseState exitState, object param) { base._OnEnter(exitState, param); owner.remainShootTime = owner.owner.fightData.shootCd; _shootTime = owner.owner.fightData.firstShootTime; owner.rawAnim.Play("attack", 0, 0); } 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) { // 开枪 _DoFire(owner.lockEnemy); isFinished = true; nextState = owner.remainBulletCount <= 0 ? EBatteryState.Reload : EBatteryState.Idle; } } private void _DoFire(GameUnit targetEnemy) { _ShowFireEffects(targetEnemy); _PlayFireAudio(); var shootCount = Mathf.Min(owner.remainBulletCount, owner.owner.fightData.perShootBulletCount); for (int i = 0; i < shootCount; i++) { owner.owner.NormalShoot(targetEnemy); } owner.remainBulletCount -= shootCount; } private void _PlayFireAudio() { var weaponConfig = owner.rawWeaponConfig; var fireAudioIds = weaponConfig.FireAudioId; if (fireAudioIds.Count <= 0) return; var fireAudioId = fireAudioIds[Random.Range(0, fireAudioIds.Count)]; AudioManager.Instance.PlayAudio(fireAudioId, owner.fireTrans.position).Forget(); } private void _ShowFireEffects(GameUnit targetEnemy) { var rawWeaponConfig = owner.rawWeaponConfig; var rootObj = owner.rootObj; var fireTrans = owner.fireTrans; var fireEffectId = rawWeaponConfig.FireEffectId; if (fireEffectId > 0) { var rot = rootObj.transform.rotation; EffectManager.instance.PlayEffectById(fireEffectId, fireTrans.position, rot); } var groundEffectId = GLConfig.Inst.data.GroundFireEffectId; if (groundEffectId > 0) { var firePos = fireTrans.position; firePos.y = 0.1f; var rot = rootObj.transform.rotation; EffectManager.instance.PlayEffectById(groundEffectId, firePos, rot); } var lineEffectId = rawWeaponConfig.FlyEffectId; if (lineEffectId > 0 && PerformanceManager.instance.data.enableBulletTail) { if (targetEnemy == null || targetEnemy.Node == null || targetEnemy.Node.GameObject == null) return; _EmitLine(fireTrans, targetEnemy.Node.GameObject.transform, rawWeaponConfig.BulletFlySpeed); } } private void _EmitLine(Transform start, Transform end, float flySpeed) { var rawWeaponConfig = owner.rawWeaponConfig; // 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); } } }