cirnogodot/Scripts/Components/FSM/Enemy/3D/NavigationProvider3D.cs

112 lines
2.8 KiB
C#
Raw Normal View History

2025-06-21 15:41:29 +02:00
using Cirno.Scripts.Utils;
using Godot;
namespace Cirno.Scripts.Components.FSM.Enemy._3D;
public partial class NavigationProvider3D : Node
{
private Vector3? _lastTargetPosition;
private CharacterBody3D _characterBody;
//private NavigationAgent3D _navigationAgent;
2025-09-25 15:50:34 +02:00
[ExportCategory("References")]
[Export]
public NavigationAgent3D NavigationAgent { get; private set; }
[Export] public EnemyStorage3D StorageModule { get; private set; }
[ExportCategory("Properties")]
2025-06-21 15:41:29 +02:00
[Export]
2025-09-25 15:50:34 +02:00
public float ProcessingRate { get; private set; } = 0.1f;
private Vector3? _nextPathPosition;
2025-06-21 15:41:29 +02:00
public void Init(CharacterBody3D characterBody)
{
_characterBody = characterBody;
if (NavigationAgent is not null) return;
2025-09-25 15:50:34 +02:00
// var timer = new Timer();
// this.AddChild(timer);
//
// timer.Timeout += TimerOnTimeout;
//
// timer.Start(ProcessingRate);
2025-06-21 15:41:29 +02:00
}
2025-09-25 15:50:34 +02:00
private void TimerOnTimeout()
{
if (!_lastTargetPosition.HasValue)
{
return;
}
if (NavigationAgent.IsNavigationFinished())
{
return;
}
_nextPathPosition = NavigationAgent.GetNextPathPosition();
}
2025-06-21 15:41:29 +02:00
public void SetTarget(Vector3? target)
{
2025-09-25 15:50:34 +02:00
_lastTargetPosition = target;
2025-06-21 15:41:29 +02:00
}
2025-09-25 15:50:34 +02:00
2025-06-21 15:41:29 +02:00
public void Move(float movementSpeed)
{
if (!_lastTargetPosition.HasValue)
{
return;
}
2025-09-25 15:50:34 +02:00
2025-06-21 15:41:29 +02:00
NavigationAgent.SetTargetPosition(_lastTargetPosition.Value);
2025-09-25 15:50:34 +02:00
2025-06-21 15:41:29 +02:00
var currentAgentPosition = _characterBody.GlobalPosition;
if (NavigationAgent.IsNavigationFinished())
{
return;
}
2025-09-25 15:50:34 +02:00
_nextPathPosition = NavigationAgent.GetNextPathPosition();
var newVelocity = !_nextPathPosition.HasValue
? Vector3.Zero
: currentAgentPosition.DirectionTo(_nextPathPosition.Value) * movementSpeed;
2025-06-21 15:41:29 +02:00
newVelocity += StorageModule.KnockbackVelocity;
2025-09-25 15:50:34 +02:00
2025-06-21 15:41:29 +02:00
if (NavigationAgent.AvoidanceEnabled)
{
NavigationAgent.SetVelocity(newVelocity);
}
else
{
_on_navigation_agent_3d_velocity_computed(newVelocity);
}
}
2025-09-25 15:50:34 +02:00
2025-06-21 15:41:29 +02:00
public void _on_navigation_agent_3d_velocity_computed(Vector3 safeVelocity)
{
if (_characterBody is null) return;
_characterBody.Velocity = safeVelocity;
if (_characterBody.Velocity.Length() > 0)
{
StorageModule.FacingDirection = _characterBody.Velocity.Normalized().ToVector2();
}
}
public bool IsNavigable(Vector3 newPos)
{
NavigationAgent.SetTargetPosition(newPos);
return NavigationAgent.IsTargetReachable();
}
public bool IsNavigationFinished()
{
return NavigationAgent.IsNavigationFinished();
}
}