Fantastic job on this project! I had a question regarding pathfinding without using 2D Physics. I’m currently using SpriteTile as an editor to create a top-down procedural 2D dungeon with non-physics colliders. I’m looking to buy the full A* version, but testing the free version out first if it meets my needs.
Currently, I seem only able to get everything to work when I have 2D physics enabled. I’ve tried playing around with different settings including height testing (given it’s 2D not sure if this should even be applicable). Any suggestions would be much appreciated, Thanks!
Then you will have to set the walkable/unwalkable values manually.
The easiest way is probably to subclass the grid graph and override the UpdateNodePositionCollision method.
public virtual void UpdateNodePositionCollision (GridNode node, int x, int z, bool resetPenalty = true) {
// Set the node's initial position with a y-offset of zero
node.position = GetNodePosition ( node.NodeInGridIndex, 0 );
node.Walkable = ...;
// Store walkability before erosion is applied
// Used for graph updating
node.WalkableErosion = node.Walkable;
}
You will have to add an attribute to the GridGeneratorEditor.cs file to make sure your new graph has an editor
So that solution has worked for me no problem. Currently I’m trying to understand how to use the procedural grid mover. Would this override the graph from being created as a whole at the beginning? (I would think this would be ideal to save time) If I keep the grid on the player does the grid and collisions update within that radius? Lastly, I plan on having enemies throughout the dungeon/world. If the grid radius is only a certain size around the player, I assume that means that enemies aren’t able to calculate a path unless the player is within a certain distance from him? Thanks a lot for the help!
The graph will ge generated using your changed UpdateNodePositionCollision method. This is also the method that the procedural grid mover indirectly calls to update the grid when it is moved.
Yes, they will only be able to calculate a path if both the target and the source is on the graph.
Well, they will be able to calculate a path otherwise as well, but that path would just move them to the closest point on the graph so it would not be of much use.
Games often disable enemies that are some distance away from the player.
Thanks for the info. I have the procedural grid mover on my player, but it’s not following him in the Y axis. I assume this is because it’s set up with XZ coordinates in mind? Is that something that I would need to change in your code (If so where?) or do you think I would be able to adjust coordinates from Z to Y in my own code?
Lastly, I’m getting a very noticeable frame rate drop every time the grid is updating, any suggestions to fix the performance? Much appreciated!
I moved onto some other work waiting for your response to my last question. Was hoping to get back to some pathfinding. Please respond when you have a chance. Thank you.
Yeah. The procedural grid mover is right now assuming that the graph is not rotated. I will try to update it when I release the next version.
However it should be fairly easy to hack it to work in the XY plane instead. The key field is the “dir” variable at the top. I actually this it should work by just changing
Int2 offset = new Int2 ( -Mathf.RoundToInt(dir.x/graph.nodeSize), -Mathf.RoundToInt(dir.z/graph.nodeSize) );
to
Int2 offset = new Int2 ( -Mathf.RoundToInt(dir.x/graph.nodeSize), -Mathf.RoundToInt(dir.y/graph.nodeSize) );
But I have not tested that. Something similar should work however.
There are some things you can try.
You can try to lower the update distance (that will make the updates faster but more frequent) but that only works to some extent. Making the grid smaller also works. Setting erosion to 0 in the grid graph will help quite a lot as well since it has to update fewer nodes. And a minor performance boost can be gained by turning off height testing and or collision testing (but I guess you want at least one enabled).
I tried your suggestion for the XY plane. It didn’t work as is. I also had to change the SqrMagnitudeXZ function in AstarMath from return delta.xdelta.x+delta.zdelta.z to return delta.x * delta.x + delta.y * delta.y. That being said, it’s kind of working, but I’m getting some odd stretching behaviour from the grid graph, so probably need to change something else somewhere. For reference:
Lastly, playing around with what you said for performance helps a bit. Making the grid smaller probably had the biggest effect. Even so, FPS is dropping from around 830 to about 20 every update so it’s extremely noticeable. It’s odd because your procedural grid mover example scene seems to run at fairly consistent frame rate. I’ll look at that again to see if there’s something I missed. Should there be additional complimentary scripts to that work with the grid mover to help? Thanks again.
Oh. I am not sure if you should modify that method. The SqrMagnitudeXZ method is used in various places in the project and changing it might break other stuff.
Hm… Odd that the procedural example scene works.
No, the procedural grid mover can be used without any other scripts (except the AstarPath script of course).
I have updated the script to support rotated grid graphs (and all other features you can use to transform it, like isometric graphs and aspect ratio).
Here is it: http://pastebin.com/xmhZ0viQ
Also. Make sure that the graph is not visible (A* Inspector -> Show Graphs) when you run the game as gizmo rendering is pretty slow.
Thanks a lot for the prompt update! Working much better now. I’ve also got the performance to be better with your suggestions. I’ll certainly look to buy the full version as I think this solution will work!
Thanks Aron. Friendly fyi on the install, I’m getting this message: Assets/AstarPathfindingProject/Core/AstarData.cs(36,24): error CS0246: The type or namespace name `LayerGridGraph’ could not be found. Are you missing a using directive or an assembly reference?
I noticed on your change log that you added a shortcut to the LayerGridGraph. Could something have been omitted? Or a name being used in the same place?
Yes. I found that bug a few days ago. I had forgot to compile that out in the free version. Simply remove that field and any references to it.
Now I have even added automated compile testing against 4 different unity versions and testing with lots of different compiler directives to make sure that it all works.