A paying customer here. I have a pretty puzzling problem using GraphUpdateObject.
I have a pretty basic setup where I use:
a Grid Graph, it starts with pretty much everything walkable, plain.
The Graph is configured to use Physics Sphere casting to check walkability as well as height testing.
Graph update batching is turned on,
In this context I try to use GraphUpdateObjects to get the graph updated whenever there are new obstacles.
The GUO is working correctly for making nodes unwalkable. However when I try to revert the changes (once the obstacle disappears) there are no changes or the extent of changes is radically smaller than of the original GUO that I try to revert.
I tried two methods:
RevertFromBackup() with trackChangedNodes
Setting modifyWalkabilty = true and setWalkability = true
Neither is having the desired effect.
From inital, very preliminary looks of it, it seems like the issue is with batching updates?
Is this feature working at all? After spending a couple of hours testing this extensively, Iâm pretty sure the issue is with the library and not my code, however of course I could be mistaken.
Usually the best way is to simply use physics for updating the graph, that means that you should not set any parameters like modifyWalkability on the GUOs, when you first instantiate an obstacle you just create a new GraphUpdateObject with the collider bounds and when you destroy it you do exactly the same thing. Make sure that you destroy the object before updating the graph because otherwise the graph update will still think that there is an obstacle there and the nodes will not be changed.
However still I have a problem getting it to work at all.
Do GUOs with changing walkability work at all with batch updates? Is that implemented? For instance if I perform GUO update 1, then a couple of lines GUO update 2, etc. etc. and these requests get batched - Iâm I guaranteed that the final result will be the same as if I just run them without batching?
I have a bit complex use-case here with many physical units moving one next to the other. If an object is moving fast enough I donât it to be taken into consideration in the pathfinding map (i.e. I want it to disappear in the map). Thatâs because itâs very difficult to reason about moving objects and the way they will interact with each other in the future. Thatâs why I used modifyWalkability.
As long as you donât do any other modifications in the meantime the result should be the same. The graph updates should be executed in the same order and give the same result (though if the graph update uses physics it can obviously depend on if objects have moved in the scene).
Iâm not sure why it is not working for you though. Are you sure the bounds object is large enough to contain the nodes (even on the y axis)?
Also, have you disabled the âupdatePhysicsâ field on the GUO (that field and modifyWalkability are mutually exclusive and updatePhysics will take precedence if I remember correctly (itâs in the docs)).
I extended the bounds by a few units and now there is some effect, though not exactly what I would expect.
When I use RevertFromBackup() it works pretty well. However this has an inavoidable issue that if there is a change A, then an overlapping change B, then I revert change A and then revert change B then I will likely get some artifacts from the change A on the map, since the âbackupâ of B contains some data from the overlapping change A.
Therefore Iâd really prefer to use modifyWalkability=true, setWalkability=true. This would more likely set some nodes as walkable where they shouldnât be, but I prefer that compromise to the above one. So I tried with the very same bounding boxes and I get kind of artifacts (see the picture attached).
So if I understand you correctly you are confused as to why the GUO with modifyWalkability=true does not always set the nodes that the GUO with updatePhysics=true affected to be walkable?
First off, your object might have moved between those two graph updates (I presume), so they might not be updated the same region of the graph.
Secondly when using physics, the actual region that is affected depends on Grid Graph Settings -> Collision Testing -> Diameter as well as Grid Graph Settings -> Erosion (though you seem to have that set to 0, so that shouldnât matter). I would suggest that you use either update physics for both calls or modifyWalkability for both calls to make sure they match.
Another option could be to use tags instead of walkability which has the positive effect of not messing up the rest of the worlds walkability values when your agents move around.
âSo if I understand you correctly you are confused as to why the GUO with modifyWalkability=true does not always set the nodes that the GUO with updatePhysics=true affected to be walkable?â
Yes, exactly.
âFirst off, your object might have moved between those two graph updates (I presume), so they might not be updated the same region of the graph.â
Hmm, but the only thing that I assign to GUO that has anything to do with gameObject is bounds. However bounds is a struct and as far as I can see contains no references to gameObject.transform or anything like that. For reverting I especially put aside a copy of the GUO to revert under OldGUO. So I believe the object moving around in between the calls shouldnât affect anything. As the thing to be reverted will be OldGUO that has the same bounds as GUO.
âSecondly when using physics, the actual region that is affected depends on Grid Graph Settings -> Collision Testing -> Diameter as well as Grid Graph Settings -> Erosion (though you seem to have that set to 0, so that shouldnât matter). I would suggest that you use either update physics for both calls or modifyWalkability for both calls to make sure they match.â
Thatâs a valid point. I could test it out. So should I extend the bounds.size by the value of Sphere cast diameter to fix that? Indeed, erosion is at 0.
âAnother option could be to use tags instead of walkability which has the positive effect of not messing up the rest of the worlds walkability values when your agents move around.â
Alright, indeed when I use modifyWalkability in both calls it works as expected. Seems the usePhysics call does some additional stuff, Iâm not aware of like looking around the bounding box for some additional changes, etc.
I like the tag idea, probably will go with that.
Out of curiosity - is the GUO using modifyWalkability / modifying tags cheaper than the one using physics? I understand the usePhysics actually performs some raycasting / spherecasting under the wraps which may be costly?
Yeah, in the game that iâm writing the physics is a bottleneck actually. There are as many as 100 units searching for paths and performing some physics computation at once.