Moving navigation region not working

Godot Version

Godot 4.7.1 Stable

Question

Hi all. I’m trying to create a navigation region on the deck of a ship, so the NPC sailors can traverse it. If the ship is still, all works nice. If the ship is moving, though, this happens:

According to the docs:

NavigationRegions will automatically push global_transform changes to the region on the NavigationServer which makes them suitable for moving platforms.

So I thought this should work out of the box, what I am missing here? I’ve been unable to find anything about moving navigation regions, so I believe I’m making a silly mistake or something, because it is impossible I’m the first person trying to achieve this scenario.

The relevant code:

Movement of the ship (a simple Node3D):

func _physics_process(_delta: float) -> void:
	ship.global_position.z -= 1.0
	ship.global_position.x += 1.0
	ship.rotate_y(deg_to_rad(0.5))

Script of the character:

class_name StickMan extends CharacterBody3D

@export var speed := 4.0
@export var navigation_agent: NavigationAgent3D

var _is_moving := false

func _ready() -> void:
	navigation_agent.velocity_computed.connect(_on_velocity_computed)

func _physics_process(_delta: float) -> void:
	if NavigationServer3D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
		return
	
	if navigation_agent.is_target_reached():
		_is_moving = false
	
	if _is_moving:
		var next_position := navigation_agent.get_next_path_position()
		var new_velocity := global_position.direction_to(next_position) * speed
		if navigation_agent.avoidance_enabled:
			navigation_agent.velocity = new_velocity
		else:
			_on_velocity_computed(new_velocity)

func move_to(destination: Vector3) -> void:
	navigation_agent.target_position = destination
	_is_moving = true

func _on_velocity_computed(safe_velocity: Vector3) -> void:
	velocity = safe_velocity
	move_and_slide()

The move_to method is called in the test scene, in the _unhandled_input method. When I press the ui_accept action (space bar), the global position of a Marker3D in the bow of the ship is sent to the method.

Might be relevant: first I attempted to make the ship move in the _process method, instead of the _physics_process, and the NavigationRegion itself was lagging behind the 3D model, but doing the movement in the _physics_process method, fixed that.

Thanks for your help!

I don’t know if this applies to you, but a while ago I saw a video of an indie dev fixing the same-ish issue. He was making a game about ships with on-ship navigation, and had movement issues too.

The way he solved it was by making a ‘still ghost’ copy of his ship to calculate the navigation, which he then applied to his moving ship.

I’ll see if I can find the video on desktop later, but on mobile I was unable.