134 lines
3.9 KiB
C#
134 lines
3.9 KiB
C#
using Components;
|
|
using System.Collections.Generic;
|
|
using GeometryTD.Entity.EntityData;
|
|
using UnityEngine;
|
|
|
|
namespace GeometryTD.Entity
|
|
{
|
|
public class EnemyEntity : EntityBase
|
|
{
|
|
private const float WaypointReachDistance = 0.05f;
|
|
|
|
private Transform _target;
|
|
private float _speed;
|
|
private MovementComponent _movementComponent;
|
|
private readonly List<Vector3> _pathPoints = new List<Vector3>();
|
|
private int _pathPointIndex;
|
|
private bool _isDespawnRequested;
|
|
|
|
protected override void OnInit(object userData)
|
|
{
|
|
base.OnInit(userData);
|
|
|
|
_movementComponent = GetComponent<MovementComponent>();
|
|
}
|
|
|
|
protected override void OnShow(object userData)
|
|
{
|
|
base.OnShow(userData);
|
|
|
|
_target = null;
|
|
_pathPoints.Clear();
|
|
_pathPointIndex = 0;
|
|
_isDespawnRequested = false;
|
|
if (userData is EnemyData enemyData)
|
|
{
|
|
_speed = enemyData.Speed;
|
|
_target = enemyData.Player;
|
|
if (enemyData.HasPath)
|
|
{
|
|
IReadOnlyList<Vector3> pathPoints = enemyData.PathPoints;
|
|
for (int i = 0; i < pathPoints.Count; i++)
|
|
{
|
|
_pathPoints.Add(pathPoints[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
_movementComponent.OnInit(_speed, CachedTransform);
|
|
_movementComponent.SetMove(true);
|
|
}
|
|
|
|
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
|
|
{
|
|
base.OnUpdate(elapseSeconds, realElapseSeconds);
|
|
|
|
if (_pathPoints.Count > 0)
|
|
{
|
|
UpdatePathMovement(elapseSeconds, realElapseSeconds);
|
|
return;
|
|
}
|
|
}
|
|
|
|
protected override void OnHide(bool isShutdown, object userData)
|
|
{
|
|
_movementComponent.SetMove(false);
|
|
_pathPoints.Clear();
|
|
_pathPointIndex = 0;
|
|
_isDespawnRequested = false;
|
|
|
|
base.OnHide(isShutdown, userData);
|
|
}
|
|
|
|
private void UpdatePathMovement(float elapseSeconds, float realElapseSeconds)
|
|
{
|
|
if (_isDespawnRequested)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_pathPointIndex >= _pathPoints.Count)
|
|
{
|
|
DespawnOnReachHouse();
|
|
return;
|
|
}
|
|
|
|
Vector3 direction = GetDirectionToPathPoint(_pathPoints[_pathPointIndex], out float distanceSquared);
|
|
if (distanceSquared <= WaypointReachDistance * WaypointReachDistance)
|
|
{
|
|
_pathPointIndex++;
|
|
if (_pathPointIndex >= _pathPoints.Count)
|
|
{
|
|
DespawnOnReachHouse();
|
|
return;
|
|
}
|
|
|
|
direction = GetDirectionToPathPoint(_pathPoints[_pathPointIndex], out _);
|
|
}
|
|
|
|
if (direction.sqrMagnitude <= Mathf.Epsilon)
|
|
{
|
|
_movementComponent.SetMove(false);
|
|
return;
|
|
}
|
|
|
|
_movementComponent.SetMove(true);
|
|
_movementComponent.SetDirection(direction);
|
|
_movementComponent.OnUpdate(elapseSeconds, realElapseSeconds);
|
|
}
|
|
|
|
private Vector3 GetDirectionToPathPoint(Vector3 worldPoint, out float distanceSquared)
|
|
{
|
|
Vector3 delta = worldPoint - CachedTransform.position;
|
|
distanceSquared = delta.sqrMagnitude;
|
|
if (distanceSquared <= Mathf.Epsilon)
|
|
{
|
|
return Vector3.zero;
|
|
}
|
|
|
|
return delta.normalized;
|
|
}
|
|
|
|
private void DespawnOnReachHouse()
|
|
{
|
|
if (_isDespawnRequested)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isDespawnRequested = true;
|
|
_movementComponent.SetMove(false);
|
|
GameEntry.Entity.HideEntity(Entity);
|
|
}
|
|
}
|
|
} |