I’m having a lot of trouble trying to connect a layered graph (upper level) to a default lower level graph during runtime. This is all using one layered gridgraph. There isn’t multiple graphs, just one layered grid-graph.
I have a ramp that is supposed to go from the lower level to a level above it, but for some reason the lower level won’t connect nodes to the ramp when I instantiate the ramp into the scene.
I’ve tried using both graphupdatescene components and doing it the old way via code using collider bounds and a graph update object. I’ve tried giving the ramp one huge collider that covers it all, and I’ve tried breaking into different parts.
The weird thing is, when I do a full scan of the scene, the graph will update perfectly using the ramp. If I just try to update the area of the ramp on the graph, it doesn’t work. Would you have any ideas?
I am using version 3.7 if that makes any difference.
It doesn’t look like the graph has been updated in that image.
Are you sure the bounds contain the object completely?
Do you have ‘updatePhysics’ enabled on the GraphUpdateObject?
Yes, that picture is actually with having tried to update the area already. Here is another picture of my graph update scene settings, and it is during runtime.
When I scan the full graph, it works correctly, but when I just try updating the local area of the ramp, it doesn’t work. Is there a reason why a full scan would make it work, but trying to update the local area (using just the bounds) would not? I’m trying to figure that out as well.
Also, I’ve tried applying the graph update area via code. Here is the code I’m using:
`public void UpdateGraphAreaOldMethod()
{
customUnitBounds = thisTransform.GetComponent<Collider>().bounds;
/*boundsX = customUnitBounds.size.x;
boundsX += 10f;
boundsZ = customUnitBounds.size.z;
boundsZ += 10f;
boundsY = customUnitBounds.size.y;
boundsY += 25.0f;
//Expand the building's bounds. This way, I make sure the area under the building gets set re-walkable completely
customUnitBounds.size = new Vector3(boundsX, boundsY, boundsZ);*/
guo = new GraphUpdateObject(customUnitBounds);
//guo.trackChangedNodes = true;
guo.updatePhysics = true;
guo.requiresFloodFill = true;//This is false originally as well
//Set the tag to "Tag 1" (i.e the second tag, starts on 0)
//guo.setTag = team;
//**node = AstarPath.active.GetNearest (transform.position,null,null).node;
//**if(node.penalty != 7000) {
//Set that tags should be modified
guo.modifyTag = true;
guo.setTag = 1;
//guo.addPenalty = 6000;
guo.modifyWalkability = true;
guo.setWalkability = true;
//path.enabledTags = (1 << 2);
//guo.trackChangedNodes = false;
//**}
AstarPath.active.UpdateGraphs(guo);
}`
I’m not sure…
Try waiting for a frame before issuing the graph recalculation. Sometimes the physics engine needs a frame before things will work (depends on when you instantiated the object).
When I update the ramp area via code, I actually am doing it on a timer. So there are several seconds between each time I try to update the area of the ramp, and it gets tried multiple times (every “x” seconds based on the timer).
Any ideas on why using the “full scan” method works though? If I stop the game during runtime, and click on the “Scan” button – it does that full scan thing, and it works. Is there something a full scan does that the graph update scene (or my code using a graph update object) doesn’t do?
Also, I’ve checked to make sure the Ramp’s layer is on the same layer that the graph does height testing for – just so you know.
A full scan should do pretty much what a full scan does, but maybe there was some bug in 3.7, I can’t remember.
Try the latest version and see if that works better.
Ok, ya that was going to be my last resort. So, I’ll try updating to the current version and see if it works. When I upgrade do I need to delete the previous version first? I can’t remember, it’s a been awhile since I updated.
Thanks for your help Aron, and hopefully updating will fix it.
Normally you should not have to delete the previous version, but I know that sometimes Unitypackages will not import properly if there is an old version in the project, so you can delete it just in case (make sure to back up your project or use version control).
Okay, I updated to the latest version available on the Unity asset store, which was 3.8.1. So, I tested things in this version and it’s still not working, unfortunately. When I try updating the graph area based on the ramp object’s collider or with points in the graphupdatescene component, it will not update the layered graph. If I scan though, it does update properly-- which I find odd. I completely deleted the old version and installed the new one. I’ve tried everything I can think of.
So, I created a completely brand new project and made a quick test scene. All I have in the project is the AstarPathfinding asset and the code and canvas I’m using to instantiate my “Ramp” during run-time. I tested this with a simple cube as well, and the layered graph just will not update for some reason?
I’m assuming the visual graphical indicators for the graph are correctly updated during runtime as well – I would hate for it to actually be working, but the visual indicators just don’t show it?
Maybe I’m missing a simple setting or doing something dumb – but I can’t get it to work. If you want me to send you my quick test project I can do that. If you would like to see my project, what is the best way to send the project to you? It’s about 205 MB.
Sure, you can send the simple test scene and I will take a look at it.
It is definitely possible that there is some bug somewhere, but graph updates are at least working in the example scenes (check out the layered grid graph example scene and press P to place an obstacle).
I’ve been doing a lot of testing recently and found some interesting things. You mentioned the layered gridgraph example scene, so I took a good look at it. Your example scene works right off the bat for me – so I was surprised as to why it did. I tried changing a few settings, and I found that it seems like only a node size of “0.5” seems to work. I tried changing the node size to “4” in your example scene, and it causes the graph to not work properly. I then tried a node size of “2”, and it still didn’t work. A node size of “1” did not either. For some reason, only a node size of 0.5 works.
So, I went back to my own test scene and set my layered gridgraph to a node size of “0.5” and it did not work. I looked at the code you were using to instantiate an object and update the graph. I noticed that you were not modifying any of the “guo” settings, but simply creating a new guo, and updating the scene with it. If I do this with my own code (in my own test scene), it DOES work. However, if I try to set the “guo” walkability to true (or mess with the tags in any way), it does NOT work. For example, if (in code) I create a new “guo”, then I say – “guo.modifyWalkability = true; and guo.setWalkability = true;” – the graph won’t update the layered level. Like I said before though, if I simply create a new guo (in code) and update the graph, it will set the layered graph to be unwalkable properly. Anything else doesn’t seem to work.
Overall, I’m not really sure what’s going on. But if you can, take a look at your own example scene, and try instantiating an object where you modify the graph walkability to be true (and maybe try switching to a different tag as well) – and see what happens for you. Also, try setting the node size to a large size and see if it works for you.
Maybe this information will give you some insight as to what is happening on my end. I was going to send you my project, but maybe that won’t be necessary if you can troubleshoot what might be happening from this information.
With those settings it should change all nodes inside the bounds to be walkable however it will not use physics to check if any nodes should change position or if new ones should be created, this simply updates existing nodes. Is this what you expected and it did not work?
I’m not sure exactly what you mean honestly. I guess, I don’t know what the “physics” setting does really – sorry. But I guess, what I am expecting, is lets say I instantiate a cube during runtime and I update it’s area on the graph. I am expecting to see blue squares on the top of the cube indicating that there is a graph there on top of the cube, and that it is walkable (just like on a regular ground layer). I don’t see this though. I do not see the graph on top of my cube when I try to make it’s area walkable. I only see the graph on top of my cube when I don’t modify anything at all (i.e. I don’t modify the walkability or the tags at all) – which is only when the graph is unwalkable. The only time I see the graph (visually) on top of my cube is when I simply create a new guo and apply it with Astar.active.UpdateGraphs(guo).
I think some pictures will help you here. So I’ll show some pictures that show what I mean.
So by default guo.updatePhysics is enabled, this will make the grid graph recalculate that region as if you would scan the graph again. If modifyWalkability or modifyTag is true, then it will not do this but instead simply modify the existing nodes in the graph. When modifyWalkability is true, all nodes inside the region will have their walkability set to ‘setWalkability’ without any regard for the settings in the grid graph such as collision testing/erosion/etc.
I know the field names are pretty bad, I have been planning to do some refactoring of the GraphUpdateObject API for some time now to make it more intuitive.
Ok ya that does help me try to understand the physics setting a little bit more. So, I’m trying to figure out if that means the upper layer of the gridgraph is being updated if I set the walkability to true and change it to a different tag? Does the graph just not visually indicate this is happening?
Because here is a picture of what happens when I don’t modify anything (using the graphupdatescene component). As you can see in this picture, it will show the upper graph layer actually is there, and that the nodes are unwalkable.
I want the nodes to be “walkable” though and have a certain tag. So this is the picture of what happens when I try to set the upper layer of the graph to walkable and with a tag:
As you can see, when I try to set the nodes to walkable, I do not see any graph at all on my cube, only the underlying ground layer graph.
Does this mean, the layered graph (upper layer) nodes are being set to walkable, with the proper tag, but I just don’t see it?
I’m going to keep testing things. Because I just tried adding the “setwalkability and set tags” code to true in your example scene (in that object placer script), and the little robot actually does walk on the cube that is instantiated.
Thanks for your continued help Aron, sorry I don’t understand your system fully yet, so I appreciate your help. I’ll keep trying to get things to work.
Let me know what you can with those pictures above, thanks.
Those settings only modify existing nodes. There is no second layer at those positions when you try to update the nodes, so not much happens.
[Edit] To clarify.
With the default settings it will use physics to check how the world has changed, it detects that you have added a box and will thus create new nodes on top of it. If you set modifyWalkability it will not use physics so when you try to update that region it will see the nodes that exist there (the ground node, there are no nodes on top of the box) and will set the walkability or tag on those nodes.
I have a feeling there’s something I just don’t understand about your system then. So the upper layer graph nodes don’t exist yet? How do I get them to “exist”?
Overall, my main question is how can I create a “ramp” object that allows a character to walk up to the next level (and I can instantiate the ramp during runtime)?
By using a GraphUpdateObject with updatePhysics set to true and modifyWalkability set to false (as setting that to true will make it ignore the updatePhysics setting as they are mutually exclusive).
And if you want to make sure the object is walkable you should make sure the grid graph settings are appropriate for that. For example make sure that the collision testing settings do not contain that object’s layer in the layer mask as that will make all nodes near it unwalkable.