This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
0 votes

So I have managed to do pathfinding with navigation2d. But now I need to also do obstacle avoidance.

    func Navigate():
        if path.size()>0:
            #print("Navigate")
            #Enemy_Character is the Enemy AI using the navigation
Enemy_Character.velocity=Enemy_Character.global_position.direction_to(path[1]) 

            if Enemy_Character.global_position==path[0]:
                path.pop_front()
        pass

    func generate_path():
        if nav2d!=null and Target!=null:
            #print("Generate Path")
            path= nav2d.get_simple_path(Enemy_Character.global_position, Target.global_position, false)

            Enemy_Character.line2d.points=path
        pass

So this navigation is working. But obstacles are not avoided. Obstacles like other enemy NPCs or magic barriers or ice barriers.

I have created 3 raycast 2ds to detect collision with other enemies and miscellaneous environment objects. But I don't know what to do next. Like ok I detected the collision but now how do I generate a new path that avoids the collision.

I have looked at some obstacle avoidance. But they're doing the navigation very differently. None of them use navigation 2d for starters. I have been working on a steering velocity. But it's kind of not working.

Navigation and collision avoidance is a very new topic for me. .Any help would be appreciated.

Godot version 3.4.4
in Engine by (208 points)

2 Answers

+1 vote

I'm trying to figure out this aswell. This is an incomplete and probably erroneous answer.
So far I've managed to pathfind using Navigation2DServer but I haven't managed to add dynamic obstacles.

I believe you have to set up Navigation2DServer and then request the path from Navigation2DServer, not to your nav2d instance.

My setup includes calling Navigation2DServer with: map_create map_set_active region_create region_set_map region_set_navpoly region_set_transform and maybe some others that I'm missing -- in other words you'll be loading a lot of info from your scene onto Navigation2DServer.

After you have set up your map and regions you'd call:

path = Navigation2DServer.map_get_path(map, pos_a, pos_b, true)

You might also want to set up agents and obstacles. I think that agents are used to avoid each other on the fly, while obstacles are 'markers' that somehow work with Navigation2DServer.

Perhaps unrelated: this issue has some images of how it's set up in Godot 4: https://github.com/godotengine/godot/issues/57967

I'm super interested in this, and there is little info on the topic. If you manage to make it work please let me know!

by (194 points)

Follow up to this: I managed to set up the whole thing in Godot 3.5, but I was dissapointed.

It seems that the core functionality is unchanged -- the navigation returns a path across all the obstacles, as if they were walkable... Collision avoidance only changes the speed and positioning of how that path is followed, sometimes moving into 'solid' areas or simply getting stuck in obstacles without finishing the path or trying to find a new viable one.
There is still no way to forbid navigation around obstacles, much less dynamic ones.

AStar is the way.

Thank you for your answer.
Will AStar have automatic collision avoidance though? I talked to someone and AStar is also only for pathfinding. Obstacle avoidance will still have to be separate. I will try AStar and let you know.

0 votes

Avoidance works with velocities, not with pathfinding or paths.

If you want pathfinding or a path not going through an obstacle you need to remove that navigation mesh below the obstacle.

In Godot 3.5+ for avoidance you define an agent's radius and position and send a wanted velocity to the NavigationServer. The server calculates a "safe" velocity considering all the other agents (obstacles are just simplified dummy agents). The NavigationAgent2D setvelocity() can be used to send the velocity and the velocitycomputed signal can be connected to receive the "safe" velocity from the server.

by (262 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.