Navigation for enemies

This commit is contained in:
Marco 2025-01-31 15:05:45 +01:00
commit 076cff208d
7 changed files with 547 additions and 297 deletions

View file

@ -0,0 +1,87 @@
using Godot;
using System;
public partial class NavigationTestEnemy : CharacterBody2D
{
[Export]
private float _movementSpeed = 300.0f;
public const float JumpVelocity = -400.0f;
private NavigationAgent2D _navigationAgent;
public override void _Ready()
{
_navigationAgent = GetNode<NavigationAgent2D>("NavigationAgent2D");
}
public override void _PhysicsProcess(double delta)
{
var mousePosition = GetGlobalMousePosition();
_navigationAgent.TargetPosition = mousePosition;
var currentAgentPosition = GlobalPosition;
var nexPathPosition = _navigationAgent.GetNextPathPosition();
var newVelocity = currentAgentPosition.DirectionTo(nexPathPosition) * (_movementSpeed);
// Navigation is over, can do other things
if (_navigationAgent.IsNavigationFinished())
{
return;
}
if (_navigationAgent.AvoidanceEnabled)
{
_navigationAgent.SetVelocity(newVelocity);
}
else
{
_on_navigation_agent_2d_velocity_computed(newVelocity);
}
MoveAndSlide();
}
public void _on_navigation_agent_2d_velocity_computed(Vector2 safeVelocity)
{
this.Velocity = safeVelocity;
}
// public override void _PhysicsProcess(double delta)
// {
// Vector2 velocity = Velocity;
//
// // Add the gravity.
// if (!IsOnFloor())
// {
// velocity += GetGravity() * (float)delta;
// }
//
// // Handle Jump.
// if (Input.IsActionJustPressed("ui_accept") && IsOnFloor())
// {
// velocity.Y = JumpVelocity;
// }
//
// // Get the input direction and handle the movement/deceleration.
// // As good practice, you should replace UI actions with custom gameplay actions.
// Vector2 direction = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
// if (direction != Vector2.Zero)
// {
// velocity.X = direction.X * Speed;
// }
// else
// {
// velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
// }
//
// Velocity = velocity;
// MoveAndSlide();
// }
}

View file

@ -3,7 +3,7 @@ using Godot;
using System;
using System.Diagnostics;
public partial class Enemy : Area2D, IDestructible
public partial class Enemy : CharacterBody2D, IDestructible
{
private InteractionController _cachedPlayer;
private EnemyState _currentState = EnemyState.Idle;
@ -61,18 +61,47 @@ public partial class Enemy : Area2D, IDestructible
public override void _PhysicsProcess(double delta)
{
HandlePlayerDetection();
if (NavigationEnabled)
{
var moveLocation = _navigationAgent.GetNextPathPosition();
// Only do these actions if the enemy has been alerted
if (_currentState is EnemyState.Primed)
{
this.Position = moveLocation;
_navigationAgent.SetTargetPosition(_cachedPlayer.GlobalPosition);
var currentAgentPosition = GlobalPosition;
var nextPathPosition = _navigationAgent.GetNextPathPosition();
var newVelocity = currentAgentPosition.DirectionTo(nextPathPosition) * (float)(WalkSpeed * delta);
// Navigation is over, can do other things like shooting
if (_navigationAgent.IsNavigationFinished())
{
// Shoot player
HandlePlayerDetection();
return;
}
if (_navigationAgent.AvoidanceEnabled)
{
_navigationAgent.SetVelocity(newVelocity);
}
else
{
_on_navigation_agent_2d_velocity_computed(newVelocity);
}
MoveAndSlide();
}
}
}
public void _on_navigation_agent_2d_velocity_computed(Vector2 safeVelocity)
{
this.Velocity = safeVelocity;
}
@ -86,10 +115,10 @@ public partial class Enemy : Area2D, IDestructible
if (IsPlayerInSight())
{
// Update player position only if player is in sight
if (NavigationEnabled)
{
_navigationAgent.SetTargetPosition(_cachedPlayer.GlobalPosition);
}
// if (NavigationEnabled)
// {
// _navigationAgent.SetTargetPosition(_cachedPlayer.GlobalPosition);
// }
Shoot();
@ -167,7 +196,7 @@ public partial class Enemy : Area2D, IDestructible
{
}
private void Explode()
{
Debug.WriteLine("Ded");

View file

@ -0,0 +1,34 @@
using Godot;
using System;
public partial class TilemapAvoidance : TileMapLayer
{
[Export] private TileMapLayer _solidLayer;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public override bool _UseTileDataRuntimeUpdate(Vector2I coords)
{
if (_solidLayer.GetUsedCellsById(0).Contains(coords))
{
return true;
}
return false;
}
public override void _TileDataRuntimeUpdate(Vector2I coords, TileData tileData)
{
tileData.SetNavigationPolygon(0, null);
}
}