2d Randomly Generated Dungeon

Hello people.

I’ve downloaded the free version of the A* Pathfinding Project and I’m finding it hard to make a working grid graph to use in my game.

Basically, I’m generating a maze / dungeon using tile prefabs. I want to then create the grid after the generation of the level. I’ve managed to create the grid, re-size the nodes to the correct size and allign them correctly with the maze but I have a couple of questions regarding changing some of the functionality via C# script. Here is my current code:

	// This holds all graph data
	AstarData data = AstarPath.active.astarData;
	
	// This creates a Grid Graph
	GridGraph gridGraph = data.AddGraph(typeof(GridGraph)) as GridGraph;
	
	// Setup a grid graph with some values
	gridGraph.rotation.x = 90.0f;
	gridGraph.center.x = ((x2 - x1) / 2) + x1;
	gridGraph.center.y = ((y2 - y1) / 2) + y1;

	gridGraph.cutCorners = false;

	gridGraph.collision.use2D = true;

	gridGraph.nodeSize = Tile.size;
	gridGraph.width = Mathf.CeilToInt(Mathf.Abs(x2 - x1) * (1 / Tile.size));
	gridGraph.depth = Mathf.CeilToInt(Mathf.Abs(y2 - y1) * (1 / Tile.size));
	gridGraph.center = new Vector3 (gridGraph.center.x, gridGraph.center.y, 0);
	
	// Updates internal size from the above values
	gridGraph.UpdateSizeFromWidthDepth();

Here is the a dungeon and the dungeon with a grid generated that I did via the inspector in unity.

This doesn’t work in code because when the grid is in 2D it needs to use a sphere instead of a capsule, which I’m having rouble changing via script. How do you do that?

Also, this generation has a handy “unwalkable when no ground” tag which you cannot enable in 2d? I’m wondering if this is an oversight or something I have to put up with?

Finally, the grid is perfectly sized to the size of my tiles in the game, but as you can see, the corridors aren’t valid paths? Do I need to make the grid size smaller, or is there something I’m missing again?

Cheers for the help!

Tommy.

Are your maps different sizes? You can set all these things in the A* GameObject you have put the AStarPath script on. If you know the size of your map during development and it will always be a 50x50 square, then you don’t even need to resize it.

I think the “unwalkable thing” stems from the fact that 3d versio shoots a ray straight down to determine things like slope. You don’t have a slope, or even a Z coordinate, so you don’t need it. If you are actually using an orthographic view of a 3d scene, treating it like 2d, then you should probably stop using the 2D pathfinding altogether. Then you won’t be needing to rotate the thing either.

And finally you need to drop the diameter of whatever collider you are using under the Collision Testing part of the AStarPath script in order for the paths to become walkable.

I think you have a lot of extra code really. You can do all that stuff in the inspector, and just keep the same GridGraph (just resize it using

AStarPath aStarPath = GetComponent();
aStarPath.Scan();

)

Is short, I recommend switching to 3d pathfinding, keeping your capsule collider, setting things like max climb and max slope to 0, setting the GridGraph options before hand, and setting your Collision Testing diameter to something small enough to pass through your corridors.

Thank you for your reply, Carroll.

I need to do the re-sizing on the fly as I don’t know the size, or dimensions of the dungeon. At the moment, I only have about five general layouts, but I’d like it to be flexible enough so I don’t have to make pre-sets.

As for the “unwalkable” thing, I get the test is using a ray cast, but that doesn’t mean the system can’t cull areas that don’t have ground in 2d? Because the system assumes that the AI can walk everywhere, which is never going to be the case for top down maze type game systems.

Also, I did try using a 3D test but then I don’t get any results. I’m not sure it’s because the test looks “downwards” (i.e. down the y-axis) regardless of the grid rotation, or that it doens’t work with 2D sprites, but either way I’ve made more progress with the 2D system at the moment.

So, I solved two of the questions I asked yesterday:

	// This holds all graph data
	AstarData data = AstarPath.active.astarData;
	
	// This creates a Grid Graph
	GridGraph gridGraph = data.AddGraph(typeof(GridGraph)) as GridGraph;
	
	// Because it's 2d we are rotating to face the camera, which looks down the z - axis
	gridGraph.rotation.x = -90.0f;
	gridGraph.center.x = ( width * nodeSize ) / 2;
	gridGraph.center.y = ( depth * nodeSize) / 2;

	// Setting to use 2d grid creation
	gridGraph.collision.use2D = true;
	gridGraph.collision.type = ColliderType.Sphere;
	gridGraph.collision.diameter = nodeSize;
	gridGraph.collision.mask = LayerMask.GetMask("Obstacles");
	
	gridGraph.nodeSize = nodeSize;
	gridGraph.width = width;
	gridGraph.depth = depth;
	gridGraph.center = new Vector3 (gridGraph.center.x, gridGraph.center.y, 0);
	
	// Updates internal size from the above values
	gridGraph.UpdateSizeFromWidthDepth();
	
	// Scans all graphs, do not call gg.Scan(), that is an internal method
	AstarPath.active.Scan();

The gridGraph.collision.type changes the test to 2d. Also, I reduced the size of the sphere test using “gridGraph.collision.diameter” and now have valid paths on my map, as the sphere could actually fit through the narrow corridors!

I think this is useful reference for anyone else trying to use the A* Pathfinding Project in 2D, which isn’t as well documented as the 3D stuff.

I might add “empty” tiles around the outside of the dungeon so that the grid generation doesn’t map the parts that cannot be reached by the AI. I’d still be interested in getting the unwalkable test working for 2D stuff…

Sweet.
As for your question, normally I would say use the Ground mask feature in the Height Testing area, but it’s disabled in 2D mode. Hmm. I’ll poke at the code a bit. I’m far from familiar with it.

So, further updates for anyone using this for 2D random stuff, here is the latest script:

public AiGridPath (int depth, int width, float nodeSize, float diameter, bool cutCorners)
{
// This holds all graph data
AstarData data = AstarPath.active.astarData;
data.cacheStartup = false;

	// This creates a Grid Graph
	GridGraph gridGraph = data.AddGraph(typeof(GridGraph)) as GridGraph;

	// Setting up the default parameters.
	gridGraph.width = width;
	gridGraph.depth = depth;
	gridGraph.nodeSize = nodeSize;

	// Because it's 2d we are rotating to face the camera, which looks down the z - axis
	gridGraph.rotation.x = 90.0f;

	// Calculating the centre based on node size and number of nodes
	gridGraph.center.x = ( width * nodeSize ) / 2;
	gridGraph.center.y = ( depth * nodeSize) / 2;
	gridGraph.center = new Vector3 (gridGraph.center.x, gridGraph.center.y, 0);

	// Enabled corner cutting, disable slop detection and change slop axis to Z
	gridGraph.cutCorners = cutCorners;
	gridGraph.maxClimb = 0;
	gridGraph.maxClimbAxis = 2;

	// Setting to use 2d grid collision detection
	gridGraph.collision.use2D = true;
	gridGraph.collision.type = ColliderType.Sphere;
	gridGraph.collision.diameter = diameter;
	gridGraph.collision.mask = LayerMask.GetMask("Obstacles");

	// Updates internal size from the above values
	gridGraph.UpdateSizeFromWidthDepth();
	
	// Scans all graphs, do not call gg.Scan(), that is an internal method
	AstarPath.active.Scan();
}

The important addition is the maxClimbAxis and maxClimb. I think this are for 3d terrain connects, where the node is too steep, so the grid isn’t created. Anyway, for 2D the axis is down the Z as previously mentioned, so it wasn’t creating connections. To be honest I’m not sure how it ever worked without this change, but this script now handles different node sizes properly.

Hope its useful to somebody.

2 Likes

Hi there,

thanks for the script. I finally managed to get this to work here is a few updated things to take into account.

Once again 2D is not a priority in this package so some things are a bit counter intuitive. You cannot from script access the “2D” boolean and instead you must change this line:

// Because it's 2d we are rotating to face the camera, which looks down the z - axisgrid
Graph.rotation.x = 90.0f;

to this:

// Because it's 2d we are rotating to face the camera, which looks down the z - axis
gridGraph.rotation.x = -90.0f;

that should fix it. did for me at least. I also noticed that when you do this the boolean of “2D” gets set automatically.

reference can be found on GridGeneratorEditor:

public static bool Is2D (GridGraph graph) {
		return Quaternion.Euler(graph.rotation) * Vector3.up == -Vector3.forward;
	}

	protected virtual void Draw2DMode (GridGraph graph) {
		EditorGUI.BeginChangeCheck();
		bool new2D = EditorGUILayout.Toggle(new GUIContent("2D"), Is2D(graph));
		if (EditorGUI.EndChangeCheck()) {
			graph.rotation = new2D ? new Vector3(graph.rotation.y - 90, 270, 90) : new Vector3(0, graph.rotation.x + 90, 0);
		}
	}

hope this helps.

Yeah, I’m sorry this is a bit counterintuitive. The ‘2D’ toggle was introduced very recently, previously to get a 2D graph one simply rotated the graph using the inspector. The reason I couldn’t just have a 2D boolean in the code is because I need to keep backwards compatibility with existing code and graph settings. When I added that toggle I really wanted to add a boolean that you could toggle in the class, but I finally decided against it because it wouldn’t be backwards compatible.
I am however considering adding a helper method for this to avoid having to set the rotation manually.

Hey,

so how to use your script? Where to attach it?

1 Like

Here is my latest yNuky.

	/* Creates the A* Pathfinding Project Grid For The Path System To Use */
	public void Initialise(int width, int depth, float nodeSize, float diameter, LayerMask layerMask, string name)
	{
		// This holds all graph data
		AstarData data = AstarPath.active.astarData;
		data.cacheStartup = true;

		// Disable path logs.
		// AstarPath.active.logPathResults = PathLog.None;

		// This creates a Grid Graph
		GridGraph gridGraph = data.AddGraph(typeof(GridGraph)) as GridGraph;

		// Name both grid graphs so we can reference them
		gridGraph.name = name;

		// Setting up the default parameters.
		gridGraph.width = width;
		gridGraph.depth = depth;
		gridGraph.nodeSize = nodeSize;

		// Because it's 2d we are rotating to face the camera, which looks down the z - axis
		gridGraph.rotation.x = 90.0f;

		// Calculating the centre based on node size and number of nodes
		gridGraph.center.x = (width * nodeSize) / 2;
		gridGraph.center.y = (depth * nodeSize) / 2;
		gridGraph.center = new Vector3(gridGraph.center.x, gridGraph.center.y, gridGraph.center.z);

		// Enabled corner cutting, disable slop detection and change slop axis to the Z
		gridGraph.cutCorners = false;
		gridGraph.neighbours = NumNeighbours.Eight;
		gridGraph.maxClimb = 0;
		gridGraph.maxClimbAxis = 2;

		// Setting to use 2d grid collision detection
		gridGraph.collision.use2D = true;
		gridGraph.collision.type = ColliderType.Sphere;
		gridGraph.collision.diameter = diameter;
		gridGraph.collision.mask = layerMask;

		// Updates internal size from the above values
		gridGraph.UpdateSizeFromWidthDepth();
	}

I haven’t touched it in a while and so may need to change / adapt it to your project. Also, there is now a new “2D” flag, but I have never touched that, as this method still worked for me.

1 Like

Thanks for the fast replay,

I am pretty new to unity and game dev. I don’t where to attach this script too :slight_smile:

Ok, I’ve attached the entire script, as that was just the function that sets up the pathfinding. This script has a lot of stuff you don’t need, so you’ll need to edit it to make it work for you. Also, you’ll need to rename it to a .cs file.

Map.txt (10.3 KB)

Do you work in a 2D project or 3D?

The unity project is in 2d.

So I don’t need the Astar Path script anymore?
The graph gets generated by the code snippet from you?:slight_smile:

BTW your generated map looks great :slight_smile:

You want me to share the actual pathfinding tool? Sorry man, you have to buy / download that from this website or the app store. I can’t share that for free. https://assetstore.unity.com/packages/tools/ai/a-pathfinding-project-pro-87744

I got the free version :slight_smile: I think i am explaining my self very bad, going to share screens