154 lines
4.5 KiB
C#
154 lines
4.5 KiB
C#
using System;
|
|
using System.Linq;
|
|
using cfg.FightCfg;
|
|
using Cysharp.Threading.Tasks;
|
|
using Framework;
|
|
using Gameplay.Unit;
|
|
using Gameplay.Vehicle.Impl;
|
|
using LTGame;
|
|
using PhxhSDK;
|
|
namespace Gameplay.Vehicle
|
|
{
|
|
|
|
using UnityEngine;
|
|
|
|
public class BaseBattery
|
|
{
|
|
|
|
public readonly NormalVehicle owner;
|
|
|
|
public GameObject rootObj;
|
|
|
|
private Transform _fireTrans;
|
|
public Transform fireTrans
|
|
{
|
|
get
|
|
{
|
|
return _fireTrans;
|
|
}
|
|
}
|
|
|
|
public DataBattery rawConfig;
|
|
|
|
public int remainBulletCount
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public GameUnit lockEnemy;
|
|
|
|
private NStateMachine<BaseBaterryState> _fsm;
|
|
|
|
/// <summary>
|
|
/// 炮台动画比较简单,直接使用Animator
|
|
/// </summary>
|
|
public Animator rawAnim;
|
|
|
|
public Transform parent;
|
|
|
|
public Transform rotateTrans;
|
|
|
|
public BaseBattery(BaseVehicle owner, Transform parent)
|
|
{
|
|
this.parent = parent;
|
|
this.owner = owner as NormalVehicle;
|
|
if (this.owner == null)
|
|
{
|
|
throw new Exception("炮台必须挂载在NormalVehicle上");
|
|
}
|
|
rawConfig = TableManager.Instance.Tables.BatteryConfig.GetOrDefault(owner.configData.weaponId);
|
|
}
|
|
|
|
public async UniTask CreateView()
|
|
{
|
|
var batteryPath = rawConfig.ModelPath;
|
|
GameUnitManager.instance.RecordLoadPath(batteryPath);
|
|
var sampleObj = await AssetManager.Instance.LoadAssetAsync<GameObject>(batteryPath);
|
|
if (sampleObj == null)
|
|
{
|
|
DebugUtil.LogError("加载炮台失败: {0}", batteryPath);
|
|
return;
|
|
}
|
|
rootObj = Object.Instantiate(sampleObj, parent);
|
|
rootObj.transform.ResetLocals();
|
|
var allTrans = rootObj.GetComponentsInChildren<Transform>();
|
|
|
|
rawAnim = rootObj.GetComponentInChildren<Animator>();
|
|
rotateTrans = rootObj.transform;
|
|
|
|
_fireTrans = allTrans.First(t => t.name == "Fire");
|
|
}
|
|
|
|
private void _InitFsm()
|
|
{
|
|
_fsm = new NStateMachine<BaseBaterryState>();
|
|
_fsm.Add(new BatteryStateIdle(this));
|
|
_fsm.Add(new BatteryStateShoot(this));
|
|
_fsm.Add(new BatteryStateReload(this));
|
|
_fsm.Add(new BatteryStateDestroyed(this));
|
|
_fsm.Add(new BatteryStateAttackEnd(this));
|
|
|
|
_fsm.ChangeState(EBatteryState.Idle);
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
_InitProp();
|
|
_InitFsm();
|
|
}
|
|
|
|
private void _InitProp()
|
|
{
|
|
remainBulletCount = owner.fightData.maxBulletCount;
|
|
}
|
|
|
|
public bool RotateTower(GameUnit targetEnemy, float dt)
|
|
{
|
|
if (rotateTrans == null)
|
|
{
|
|
return false;
|
|
}
|
|
var turnSpeed = rawConfig.TurnSpeed;
|
|
var turnDt = turnSpeed * dt;
|
|
var isMatchAngle = false;
|
|
if (targetEnemy == null || targetEnemy.isDisposed)
|
|
{
|
|
// 炮台回正
|
|
var localYaw = rotateTrans.localEulerAngles.z;
|
|
var newYaw = Mathf.MoveTowardsAngle(localYaw, 0, turnDt);
|
|
rotateTrans.localEulerAngles = new Vector3(0, 0, newYaw);
|
|
}
|
|
else
|
|
{
|
|
// 炮台转向目标
|
|
var targetPos = targetEnemy.transData.pos;
|
|
var selfPos = rootObj.transform.position;
|
|
var toTarget = targetPos - selfPos;
|
|
toTarget.y = 0;
|
|
var ownerForward = owner.transform.forward;
|
|
var targetYaw = Vector3.SignedAngle(ownerForward, toTarget, Vector3.up);
|
|
var nowYaw = rotateTrans.localEulerAngles.z;
|
|
var deltaAngle = Mathf.Abs(Mathf.DeltaAngle(nowYaw, targetYaw));
|
|
if (deltaAngle < turnDt)
|
|
{
|
|
rotateTrans.localEulerAngles = new Vector3(0, 0, targetYaw);
|
|
isMatchAngle = true;
|
|
}
|
|
else
|
|
{
|
|
var newYaw = Mathf.MoveTowardsAngle(nowYaw, targetYaw, turnDt);
|
|
rotateTrans.localEulerAngles = new Vector3(0, 0, newYaw);
|
|
}
|
|
}
|
|
return isMatchAngle;
|
|
}
|
|
|
|
public void LogicUpdate(float dt)
|
|
{
|
|
_fsm.LogicUpdate(dt);
|
|
}
|
|
|
|
}
|
|
}
|