I am working with NavigationRegion3D and NavigationAgent3D in Godot 4.7.stable to have an NPC go somewhere. Every now and again it will get stuck behind an obstacle of some sort and I need it to notice this problem and try something else. I appreciate the various Cell and Distance and Offset settings available to me and I can influence the outcome by changing these values but given the number of moving parts in my game there will occasionally be cases where the NPC gets stuck however big I make these clearances or for example a door has closed and the NPC is now simply banging its head on that door.
The solution I have come up with is the code below. It’s in the physics process alongside the navigation agent calls to get_next_path_position() etc. Essentially it checks every so often how far the NPC has covered since the last time check. If it hasn’t covered the expected distance then assume it is stuck, hop backwards the equivalent of about 2 paces and try again. My NPC moves at about 1 unit/second so I’ve got the variables set at 2 units and 5 seconds, a distance it should easily have covered in that time.
var now: float = Time.get_unix_time_from_system()
if (now - stuck_last_timecheck) > stuck_time_gap:
if global_position.distance_squared_to(stuck_last_location) < stuck_distance_sq:
print(first_name + " is stuck")
print("time_diff:" + str(now - stuck_last_timecheck) + " distance:" + str(global_position.distance_to(stuck_last_location)) )
# try to resolve the problem by stepping back a bit and triggering the map to be baked again
velocity = direction.rotated(Vector3(0,1,0), deg_to_rad(randi_range(135,225))) * walk_speed * 50
move_and_slide()
var nav: NavigationRegion3D = get_tree().get_root().get_node("Player").nav_region
if !nav.is_baking():
nav.bake_navigation_mesh()
stuck_last_location = global_position
stuck_last_timecheck = now
This is working for me and at once every 5 seconds or so it is not adversely affecting the workload. My question is this - Am I doing the right sort of thing here or are there tools available that I just haven’t heard about yet?