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"); } 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; newVelocity += StorageModule.KnockbackVelocity; 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(); } }