#AI Pathing stuck in choosing direction.

17 messages · Page 1 of 1 (latest)

pure shadow
#

The .GIF probably isn't showing it correctly, but it's rapidly deciding between going left or going right here. This seems to very rarely happen and if I had to guess, it's a case of both paths being of equal distance to one another, so it's having trouble picking one to go with? I'm not sure.

What can I do to make sure this doesn't happen again?

#

(specifically I'm talking about the white cat at the bottom)

vast tulip
#

possible that it is because the paths are very equal for the pathfinding, but the real bug is to update paths so rapidly, that is a bug in itself. If you do that regularly, e.g. update every single frame, you will face many issues up to getting your agents stuck for real at high frame rate.

proven rune
#

Also, following the examples from the documentation ( https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationagents.html#actor-as-characterbody3d ), this should not be happening in your code.

If you can't fix it with smix8 remarks, please make a screenshot of the code involving generating and using the NavigationAgent2D.

steady flare
#

You want its navigation node thingy to be at the exact centre of the rotation (so the centre of the node that gets flipped)

proven rune
pure shadow
# vast tulip possible that it is because the paths are very equal for the pathfinding, but th...

This is probably my issue, so now I'm not entirely sure how this should work. As it stands, I have this being called every frame in a _process for as long as target is valid:

                nav.target_position = target.global_position
                direction = nav.get_next_path_position() - global_position
                direction = direction.normalized()

I'm very interested in learning how to do this properly if this is improper.

#

nav being a NavigationAgent2D

pure shadow
#

I ask this because of you bringing up how the agent is generated.

proven rune
#

The NavigationAgentXD should rest directly under the node which is moving (for most cases). However setting the target_position every physics frame is expensive (as a new path needs to be calculated every frame) and most of the time this is not necessary (even for moving targets).

You could use a Timer for that which does it (e.g.) all 40ms or using this snippet doing it every X physics frames inside the physics_process(delta):

#inside the physics_process function

# only sample the target's position every 10 physics frames
if Engine.get_physics_frames() % 10 == 0:
  nav.target_position = target.global_position
#

x % n returns the remainder of x by a division by n. If the remainder is 0 it means there is no rest after the division, it can be split evenly. If n is 10 and the physics frames rise by one(1) every time, after 10 cycles the modulo will by 0 again.

#

You can plug into n any positive integer. If you don't want this to be frame dependent, but use human readable time intervals (e.g. milliseconds) you need to ask the game engine for the frame per second of the physics engine and do some calculations. Per default the physics engine in Godot uses 60 fps. So % 60 means every in-game second.
(Caveat emptor: Be aware this is not necessary in real time, because then you would have to work with the provided delta and some extra time keeping variable.).

pure shadow
#

Thank you so much. I'm always happy to learn that I'm not only likely fixing a bug, but also saving myself on performance down the line. I'll definitely give this a shot.

vast tulip
#

You can use a timer but when you think about it there are only 2-3 situations that you can track where a navigation path needs to be updated. The navigation map has changed. You dont need to handle this, the agent auto updates the path when this happens. The path target is some node that you track, you only need to update the path when this node has moved too far away from the current target so check the distance between target position and target before you set a new path target. The target itself is no longer valid, sure set a new target, just dont do this every frame.

#

So there is never really a situation where you need to update your target position more than once each or maybe twice a second, and even than, ask if it is needed, does it really matter that the path is super-up-to-date. Most games run pathfinding updates as low as 1-2 fps even when they need to stay current, they update even less when things are happening off screen. If you look at most e.g. Unity games, the path update takes 1-2 second, it is just the character that plays a "turn" animation on the spot until the path is ready because most games with a lot of actor do the path search async.