cirnogodot/Scripts/Components/FSM/Enemy/NavigationMovementModule.cs
2025-03-25 15:15:04 +01:00

80 lines
No EOL
2.1 KiB
C#

using Godot;
namespace Cirno.Scripts.Components.FSM.Enemy;
public partial class NavigationMovementModule : Node2D
{
private Vector2? _lastTargetPosition;
private CharacterBody2D _characterBody;
private NavigationAgent2D _navigationAgent;
[Export]
public EnemyStorageModule StorageModule { get; private set; }
public void Init(CharacterBody2D characterBody)
{
_characterBody = characterBody;
if (_navigationAgent is not null) return;
_navigationAgent = this.GetNode<NavigationAgent2D>("NavigationAgent2D");
}
public void SetTarget(Vector2? target)
{
_lastTargetPosition = target;
}
public void Move(float movementSpeed)
{
if (!_lastTargetPosition.HasValue)
{
return;
}
_navigationAgent.SetTargetPosition(_lastTargetPosition.Value);
var currentAgentPosition = _characterBody.GlobalPosition;
if (_navigationAgent.IsNavigationFinished())
{
return;
}
var nextPathPosition = _navigationAgent.GetNextPathPosition();
var newVelocity = currentAgentPosition.DirectionTo(nextPathPosition) * movementSpeed;
if (_navigationAgent.AvoidanceEnabled)
{
_navigationAgent.SetVelocity(newVelocity);
}
else
{
_on_navigation_agent_2d_velocity_computed(newVelocity);
}
_characterBody.MoveAndSlide();
}
public void _on_navigation_agent_2d_velocity_computed(Vector2 safeVelocity)
{
if (_characterBody is null) return;
_characterBody.Velocity = safeVelocity;
if (_characterBody.Velocity.Length() > 0)
{
StorageModule.FacingDirection = _characterBody.Velocity.Normalized();
}
}
public bool IsNavigable(Vector2 newPos)
{
_navigationAgent.SetTargetPosition(newPos);
return _navigationAgent.IsTargetReachable();
}
public bool IsNavigationFinished()
{
return _navigationAgent.IsNavigationFinished();
}
}