Enemy navigation avoidance gives me weird safe velocity

Version 4.1.2 mono

I am using a NavigationAgent2D for my enemy pathfinding AI, and I want to use obstacle avoidance whenever a bunch of enemies crowd around a target position. By setting the velocity normally, the enemy works just fine, but when I set it to safe_velocity, the enemy only changes direction when its velocity is set to 0. I printed the raw and safe velocities, and it shows that the raw velocity provides the updated, correct velocity. In contrast, the safe velocity gives me the same velocity as before until the raw velocity is 0.

Enemy code:

extends CharacterBody2D
class_name Enemy

const SMOOTHNESS = 10

@export var range := 1.0 # In pixels
@export var interval := 1.0
@export var damage := 5
@export var speed := 10
@export var target := Target.BUILDINGS

@onready var _root := Main.get_root()
@onready var _navigation := get_node("Navigation")
@onready var _timer := get_node("Timer")

var _velocity := Vector2.ZERO

func _ready():
	_timer.connect("timeout", _on_timeout)
	_navigation.connect("velocity_computed", _on_velocity_computed)

# Basically _process but for the physics engine.
func _physics_process(delta):
	if _navigation.is_navigation_finished():
		_velocity = Vector2.ZERO
		_velocity = position.direction_to(_navigation.get_next_path_position()) * speed
	_navigation.velocity = _velocity
	print("Raw: " + str(_velocity))

func _on_timeout():
	_navigation.target_position = get_global_mouse_position()

func _on_velocity_computed(safe_velocity):
	velocity = safe_velocity
	print("Safe: " + str(safe_velocity))

For testing purposes, the target position is set to the mouse position every 0.1 seconds.

Please test with a more recent Godot version. There have been a number of NavigationAgent and avoidance changes and fixes in the past 3 months since Godot 4.1.2 was released. Avoidance is also rather difficult to debug from just a script example or text description, it usually requires the full context of a test project.

1 Like