TheSHEEEP / godotdetour

A GDNative implementation of the detour/detourcrowd library for Godot.
MIT License
121 stars 20 forks source link

Agent ignoring off-mesh links that are far apart #8

Open mikeant42 opened 3 years ago

mikeant42 commented 3 years ago

Hello, sorry to fill up your issues with basic questions but I'm running into another problem. I set up an agent and link like this:

.........

navigation.initialize(map, navParams)

var weights :Dictionary = {}
weights[0] = 1.0        # Ground
weights[1] = 1.0        # Road
weights[2] = 1.0    # Water
weights[3] = 1.0        # Door
weights[4] = 1.0        # Grass
weights[5] = 0.05       # Jump
navigation.setQueryFilter(0, "default", weights)

var params = DetourCrowdAgentParameters.new()
params.position = agent.global_transform.origin
params.radius = 3
params.height = 6
params.maxAcceleration = agent.maxAcceleration
params.maxSpeed = agent.maxSpeed
params.filterName = "default"
params.anticipateTurns = true
params.optimizeVisibility = true
params.optimizeTopology = true
params.avoidObstacles = true
params.avoidOtherAgents = true
params.obstacleAvoidance = 1
params.separationWeight = 5.0
detourCrowdAgent = navigation.addAgent(params)

yield(navigation, "navigation_tick_done")
var start = get_node("CSGSphere").global_transform.origin
var end = get_node("CSGSphere2").global_transform.origin
off_mesh = navigation.addOffMeshConnection(start, end, true, 5.35, 5) # declared in global scope this time!
navigation.rebuildChangedTiles()

And the debug mesh displays the link as in the demo jumplinkscreen

But the agent completely ignores it and will never take the path (pathfinding works well otherwise). I get no console messages except occasionally applyNewTarget: Unable to request detour move target., which seems innocuous as the player does sometimes jump high or seem to be temporarily outside the navmesh bounds. This doesn't seem to interrupt the pathfinding.

Thanks for your time, and let me know if you need more information. Any help is appreciated!

TheSHEEEP commented 3 years ago

I'm afraid I can't really help you much with this one.

Other than the test in the demo, I haven't done anything with off-mesh connections in my own project (no need for them in my case). To be honest, I was quite surprised myself when I put it into the demo and it "just worked". :laughing: It is entirely possible there is a bug or a problem with the usage.

I do know that the applyNewTarget: Unable to request detour move target. error happens only when dtCrowd itself (the underlying recast class) is not able to request a move target. Which in turn means that for that request, no navigation will happen.
Might or might not be related to the off-mesh connection problem.

Other than suggesting to try and find out what exactly the difference is between demo and your project (maybe try and use your exact geometry in the demo), I can't really offer advice here.

mikeant42 commented 3 years ago

Thanks, I'll take a closer look at the demo and try to find out where the problem is.

mikeant42 commented 3 years ago

Playing around with the demo more I noticed that in some cases the portals don't work. Moving the link back to around where it used to be and it works.

demoportals

EDIT okay it seems like the distance between the two portals can't be very large, or else the agent will just ignore it. I'm not sure why, but moving them close together makes it work (resolves the issue in my project as well). I'd also like to say this plugin is awesome. It's so much better than the Godot navigation library (even with some bugs).

TheSHEEEP commented 3 years ago

Interesting.

To be honest, this could be pretty much anything, from a bug in recast/detour itself (would have to check their demo on https://github.com/recastnavigation/recastnavigation to see if this can be reproduced) to the way I build the geometry or the way it is rebuilt on a change.

I do not really have a lot of time at the moment to spend on this project, but I'll take a look Monday or Tuesday to see if I can find a quick solution. If not, I'll at least add a note that this feature is definitely not safe to use for production.

Does this only happen when you change / add an off-mesh connection after the geometry had already been built (and thus do a rebuildChangedTiles) or does it also happen when you add the off-mesh connection before initializing the navigation?

mikeant42 commented 3 years ago

This still happens even when adding before navigation.init and never calling rebuildChangedTiles

TheSHEEEP commented 3 years ago

Well, the "good" news is that recast/detour itself exhibits the same behavior in their own demo. So this is either working as intended (why, though?) or a bug within recast/detour.

I went ahead and created an issue about this on their repo, maybe someone will share some insight: https://github.com/recastnavigation/recastnavigation/issues/477

The bad news is then, obviously, that unless they change their implementation or offer advice on how to make it work for longer ranges, there is nothing I can do about it.

I'd really love a more flexible "portal" feature in this library, but it seems that the only way for that would be to implement it myself completely (and not utilizing recast's off-mesh connections at all).
Certainly doable, but not something I have time to do at the moment as this project isn't my main focus right now.

Sorry, not the best outcome, I know. But at least now we know.
I'll add a note about this shortcoming to off-mesh connections to the readme.

tavurth commented 2 years ago

You could use a chain of off-mesh links slightly outside the map.

A-----------------------------B
 \...1....2....3....4....5.../

But it's quite cumbersome