重构清理敌人类

This commit is contained in:
2026-09-15 11:07:01 +08:00
parent 421f8bf619
commit 88ed35e757
34 changed files with 568 additions and 457 deletions
@@ -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;
}
}
}