重构清理敌人类
This commit is contained in:
@@ -1,83 +1,24 @@
|
||||
using SepCore.Components;
|
||||
using SepCore.CustomUtility;
|
||||
using SepCore.Definition;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace SepCore.Entity
|
||||
{
|
||||
public class MeleeEnemy : EnemyBase
|
||||
{
|
||||
private enum AttackStateType
|
||||
{
|
||||
Idle,
|
||||
Check_OutRange,
|
||||
Check_InRange,
|
||||
Attack
|
||||
}
|
||||
|
||||
private MovementComponent _movementComponent;
|
||||
|
||||
private float _attackRange = 1f;
|
||||
private float _attackCooldown = 1f;
|
||||
private int _attackDamage = 1;
|
||||
|
||||
private float _sqrAttackRange;
|
||||
|
||||
private AttackStateType _attackState = AttackStateType.Idle;
|
||||
|
||||
private EnemyData _meleeEnemyData
|
||||
{
|
||||
get => _enemyData;
|
||||
set => _enemyData = value;
|
||||
}
|
||||
|
||||
private EnemyStateType enemyState = EnemyStateType.Idle;
|
||||
private TargetableObject _targetableTarget;
|
||||
|
||||
protected override TargetableObjectData _targetableObjectData => _meleeEnemyData;
|
||||
public override float AttackRange => _attackRange;
|
||||
|
||||
public override ImpactData GetImpactData()
|
||||
{
|
||||
return new ImpactData(_meleeEnemyData.Camp, _attackDamage);
|
||||
}
|
||||
|
||||
#region FSM
|
||||
|
||||
protected override void OnInit(object userData)
|
||||
{
|
||||
base.OnInit(userData);
|
||||
|
||||
_movementComponent = GetComponent<MovementComponent>();
|
||||
_healthComponent = GetComponent<HealthComponent>();
|
||||
}
|
||||
#region Lifecycle
|
||||
|
||||
protected override void OnShow(object userData)
|
||||
{
|
||||
base.OnShow(userData);
|
||||
|
||||
if (userData is EnemyData enemyData)
|
||||
{
|
||||
_meleeEnemyData = enemyData;
|
||||
_healthComponent.OnInit(enemyData.MaxHealthBase);
|
||||
_movementComponent.OnInit(_meleeEnemyData.SpeedBase, this.CachedTransform, null, true);
|
||||
_movementComponent.SetMove(true);
|
||||
|
||||
_attackRange = Mathf.Max(0.1f, _meleeEnemyData.AttackRange);
|
||||
_attackCooldown = Mathf.Max(0.01f, _meleeEnemyData.AttackCooldown);
|
||||
_attackDamage = Mathf.Max(1, _meleeEnemyData.AttackDamage);
|
||||
_sqrAttackRange = _attackRange * _attackRange;
|
||||
|
||||
StartAttackCooldown(_attackCooldown);
|
||||
_attackState = AttackStateType.Idle;
|
||||
_targetableTarget = null;
|
||||
|
||||
this.CachedTransform.position = enemyData.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"Invalid data type. Data type: {userData?.GetType()}");
|
||||
}
|
||||
_sqrAttackRange = AttackRange * AttackRange;
|
||||
enemyState = EnemyStateType.Idle;
|
||||
_targetableTarget = null;
|
||||
}
|
||||
|
||||
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
||||
@@ -89,11 +30,8 @@ namespace SepCore.Entity
|
||||
|
||||
protected override void OnHide(bool isShutdown, object userData)
|
||||
{
|
||||
_movementComponent.OnReset();
|
||||
_healthComponent.OnReset();
|
||||
_targetableTarget = null;
|
||||
CancelAttackCooldown();
|
||||
_attackState = AttackStateType.Idle;
|
||||
enemyState = EnemyStateType.Idle;
|
||||
|
||||
base.OnHide(isShutdown, userData);
|
||||
}
|
||||
@@ -108,74 +46,73 @@ namespace SepCore.Entity
|
||||
|
||||
private void UpdateAttackState(float elapseSeconds)
|
||||
{
|
||||
switch (_attackState)
|
||||
switch (enemyState)
|
||||
{
|
||||
case AttackStateType.Idle:
|
||||
SetMove(false);
|
||||
case EnemyStateType.Idle:
|
||||
Movement.SetMove(false);
|
||||
if (HasValidTarget())
|
||||
{
|
||||
TransitionTo(AttackStateType.Check_OutRange);
|
||||
TransitionTo(EnemyStateType.Seek);
|
||||
}
|
||||
|
||||
break;
|
||||
case AttackStateType.Check_OutRange:
|
||||
case EnemyStateType.Seek:
|
||||
if (!HasValidTarget())
|
||||
{
|
||||
TransitionTo(AttackStateType.Idle);
|
||||
TransitionTo(EnemyStateType.Idle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsTargetInRange())
|
||||
{
|
||||
TransitionTo(AttackStateType.Check_InRange);
|
||||
TransitionTo(EnemyStateType.Chase);
|
||||
return;
|
||||
}
|
||||
|
||||
SetMove(true);
|
||||
_movementComponent.SetDirection(GetTargetDirection());
|
||||
Movement.SetMove(true);
|
||||
Movement.SetDirection(GetTargetDirection());
|
||||
break;
|
||||
case AttackStateType.Check_InRange:
|
||||
case EnemyStateType.Chase:
|
||||
if (!HasValidTarget())
|
||||
{
|
||||
TransitionTo(AttackStateType.Idle);
|
||||
TransitionTo(EnemyStateType.Idle);
|
||||
return;
|
||||
}
|
||||
|
||||
SetMove(false);
|
||||
Movement.SetMove(false);
|
||||
if (!IsTargetInRange())
|
||||
{
|
||||
TransitionTo(AttackStateType.Check_OutRange);
|
||||
TransitionTo(EnemyStateType.Seek);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_canAttack)
|
||||
{
|
||||
ResetAttackCooldown(_attackCooldown);
|
||||
TransitionTo(AttackStateType.Attack);
|
||||
ResetAttackCooldown(AttackCooldown);
|
||||
TransitionTo(EnemyStateType.Attack);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void TransitionTo(AttackStateType newState)
|
||||
private void TransitionTo(EnemyStateType newState)
|
||||
{
|
||||
_attackState = newState;
|
||||
enemyState = newState;
|
||||
|
||||
if (_attackState == AttackStateType.Check_InRange)
|
||||
if (enemyState == EnemyStateType.Chase)
|
||||
{
|
||||
SetMove(false);
|
||||
Movement.SetMove(false);
|
||||
}
|
||||
|
||||
if (_attackState == AttackStateType.Attack)
|
||||
if (enemyState == EnemyStateType.Attack)
|
||||
{
|
||||
SetMove(false);
|
||||
Movement.SetMove(false);
|
||||
ExecuteAttack();
|
||||
TransitionTo(AttackStateType.Check_InRange);
|
||||
TransitionTo(EnemyStateType.Chase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool HasValidTarget()
|
||||
{
|
||||
if (_target == null) return false;
|
||||
@@ -192,7 +129,7 @@ namespace SepCore.Entity
|
||||
{
|
||||
if (_target == null) return false;
|
||||
|
||||
Vector3 delta = _target.position - this.CachedTransform.position;
|
||||
Vector3 delta = _target.position - CachedTransform.position;
|
||||
delta.y = 0f;
|
||||
return delta.sqrMagnitude <= _sqrAttackRange;
|
||||
}
|
||||
@@ -208,31 +145,9 @@ namespace SepCore.Entity
|
||||
return;
|
||||
}
|
||||
|
||||
int damage = AIUtility.CalcDamageHP(_attackDamage, null, targetImpactData.DefenseStat,
|
||||
int damage = AIUtility.CalcDamageHP(AttackDamage, null, targetImpactData.DefenseStat,
|
||||
targetImpactData.DodgeStat);
|
||||
_targetableTarget.ApplyDamage(this, damage);
|
||||
}
|
||||
|
||||
private void SetMove(bool value)
|
||||
{
|
||||
if (_movementComponent != null)
|
||||
{
|
||||
_movementComponent.SetMove(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetTargetDirection()
|
||||
{
|
||||
if (_target == null)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
return new Vector3(
|
||||
_target.position.x - this.CachedTransform.position.x,
|
||||
0f,
|
||||
_target.position.z - this.CachedTransform.position.z
|
||||
).normalized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user