Custom GridGraphRules Overwrite Walkability After Collision Testing

Hello! I have been extending a procedural generation system that utilizes the custom grid graph rules system along with Unity jobs. I have been at a lost on why objects with colliders with appropriate layer mask(s) were not being picked up during scans.

I believe the the answer may lie in my custom grid rule. One of the method parameters for GridGraphRules.AddJobSystemPass is the enum, ‘Pass’. I currently set this to ‘AfterConnections’. There is a value of ‘BeforeCollisions’, but I am finding that most of the node data really isn’t valid at this point… i.e. my custom rule does not modify walkability at all.

So my question is whether there are any alternatives? Would manual runtime updates be the only solution? Is there a way to re-test collisions after grid graph rules are processed?

Thank you for your time. I’ve attach a code snippet of by grid rule.

	public class WalkabilityRule : GridGraphRule {
		public override void Register(GridGraphRules rules) {
			rules.AddJobSystemPass(Pass.AfterConnections,
				ctx => {
					var positions    = ctx.data.nodePositions.ToArray();
					var hasTilesList = new List<bool>();

					foreach (var position in positions) {
						bool hasTile;
						var  worldPosBoundary = BoundaryTilemap.WorldToCell(position);
						var  worldPosGround   = GroundTilemap.WorldToCell(position);
						var  hasTileGround    = GroundTilemap.HasTile(worldPosGround);
						var  hasTileBoundary  = BoundaryTilemap.HasTile(worldPosBoundary);

						if (!hasTileGround || hasTileBoundary )
							hasTile = false;
						else
							hasTile = true;
						
						hasTilesList.Add(hasTile);
					}

					var hasTileNativeArray = new NativeArray<bool>(hasTilesList.ToArray(), Allocator.Persistent);

					var walkabilityJob = new WalkabilityJobData {
						Bounds        = ctx.data.bounds,
						WalkableNodes = ctx.data.nodeWalkable,
						NodeNormals   = ctx.data.nodeNormals,
						HasTiles      = hasTileNativeArray
					};

					var handle = walkabilityJob.Schedule(ctx.tracker.AllWritesDependency);
					handle.Complete();
					hasTileNativeArray.Dispose();
				});
		}
		
		[BurstCompile]
		struct WalkabilityJobData : IJob, INodeModifier {
			public IntBounds           Bounds;
			public NativeArray<float4> NodeNormals;

			[ReadOnly] public NativeArray<bool> HasTiles;

			public NativeArray<bool> WalkableNodes;

			public void Execute() {
				ForEachNode(Bounds, NodeNormals, ref this);
			}

			public void ModifyNode(int dataIndex, int dataX, int dataLayer, int dataZ) {
				WalkableNodes[dataIndex] = HasTiles[dataIndex];
			}
		}
	}

Hi

Your rule completely overwrites walkability. So regardless of whether the collision checks made a node walkable or not, your rule will completely overwrite that. Is this what you want?
Maybe you want to AND the walkability, i.e. WalkableNodes[dataIndex] &= HasTiles[dataIndex] ?

Also. Fyi. I know you are probably just doing prototyping, but ideally when making burst grid graph rules you should:

  1. Allocate arrays using ctx.tracker.NewNativeArray(...). Then the de-allocation of them will be managed separately and you don’t have to care about it.
  2. Schedule jobs using job.Schedule(ctx.tracker); Then dependencies will be handled automatically and you don’t have to care about them. You do not have to call handle.Complete() on your job in this case.

You probably also want to modify walkability in the BeforeConnections phase (or possibly AfterErosion), not during AfterConnections. Otherwise, your walkability data will not be taken into account when calculating node connections.

Thanks for the insight Aron. I’ve modified my logic with your recommendations and now the rule is modifying walkability as I intended.

1 Like