Fixing get_next_path_position before NavigationServer map synchronization

Bram’s solution for fixing this minor error will work, but reacquiring the target multiple times every frame (because _process() is called more frequently than _physics_process()) is not optimal. Not a big deal, but it’s the principle of the thing (what if we had 10-million enemies, etc., etc.). Fortunately, there’s actually a nicer solution, which basically amounts to not having the Enemy’s NavigationAgent3D query a target on the first frame. Shown here:

(This issue was reopened for some reason, but the proposed solution from the first time around works just fine). Exact code I used in the Enemy script (and this would be useful for anything that requires you to skip a frame for initialization purposes):

func _ready() -> void:
	#<omitted irrelevant code>

	#disable enemy's _physics_process(), then defer a call of
		#dump_first_physics_frame() until after this frame's processing
	set_physics_process(false)
	call_deferred("dump_first_physics_frame")

func dump_first_physics_frame() -> void:
	#wait until just before the second physics_frame is ready to go, then
		#re-enable _physics_process()
	await get_tree().physics_frame
	set_physics_process(true)
	
func _physics_process(delta: float) -> void:
	#same code as Bram
	navigation_agent_3d.target_position = player.global_position
	var next_position = navigation_agent_3d.get_next_path_position()
4 Likes

Privacy & Terms