Help with 3D enemy navigation

Godot Version

4.2.1 (Steam)

Question

I am running into some issues following some 3D navigation tutorials. I am trying to have my robot enemy follow the player around, but for some reason instead of going to the next navigation point, it is trying to go straight to the player, meaning if there is a wall in between the player and robot, the robot will not navigate around the wall and will keep pushing against the wall. I have the navigation debug on, and the red lines do try to navigate the robot around walls, but the robot simply does not follow this line for some reason.

My level script, with a navigationregion3D base node:
extends NavigationRegion3D

@onready var player = $Player

func _physics_process(delta):
get_tree().call_group(“enemy”, “update_target_location”, player.global_position)

My enemy script, with a characterbody3D base node:

extends CharacterBody3D

@onready var animator = $AnimatedSprite3D
@onready var audio = $AudioStreamPlayer
@onready var navagent : NavigationAgent3D = $NavigationAgent3D
@export var HEALTH = 100
@export var SPEED = 3.0

var gravity = ProjectSettings.get_setting(“physics/3d/default_gravity”)
var hurting = false
var dead = false
var readytonav = false
func _ready():
animator.play(“idle”)
await get_tree().process_frame
readytonav = true

func _physics_process(delta):
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta
if HEALTH <= 0:
die(delta)
if readytonav and not dead:
var direction = ( navagent.get_next_path_position() - global_position).normalized()
translate(direction * SPEED * delta)
velocity = velocity.move_toward(direction,.25)

move_and_slide()

func update_target_location(target_location):
navagent.target_position = target_location

func die(delta):
dead = true
animator.play(“hurt”)
audio.play()
await get_tree().create_timer(50 * delta).timeout
queue_free()

Screenshot in-game:

The NavigationAgent path_desired_distance and target_desired_distance control when an agent moves the internal path index to the next path point. If this distance is very large agents can skip corners.

No, not this, I have fiddled with that a ton and when set to low the thing simply doesn’t move, and I have set it as low as possible while still having it move. I have just noticed that it seems to be stuttering in between the actual path and the direct position it has to the player, which makes me think somehow there are two forces, one is bringing it straight to the player, the other bringing it on the path, but the one going straight to the player is stronger.

Also, please define “large”

In relation to your movement speed and physics tick.

You want that desired distance value as small as possible just so your agent does not over- or undershoot path positions all the time when the agent update happen on the physics tick. A slow moving agent with a fast physics tick rate can use smaller values while a fast moving agent with a low physics tick rate will need a much larger value.

If you agent can not follow the path very close, e.g. gets pushed by physics collision or follows avoidance velocities, the desired distances might also need to be increased to avoid backtracking to overshoot path positions.

In your script you use Node3D.translate(), that changes the nodes position as an offset, but you also use CharacterBody3D physics move_and_slide() movement based on velocity that also changes your node position with physics.

That will give you conflict, use just one method / system for movement but not both at the same time. You can find script examples for agent movement in the documentation here Using NavigationAgents — Godot Engine (latest) documentation in English

Holy crap, that was it, thanks!