Hi @aron_granberg, sorry to bother you again, but I am still struggling with this issue.
I’ve tried checking if neighbourDataIndex isn’t out of bounds of the nodePositions but there is something that I don’t understand.
The results are pretty unexpected and change between scanning. I mean the situation when I repeatedly press the “scan” button. Sometimes I don’t get the exception and sometimes I do.
After adding the checking for the index to be inside bounds it makes things even more unpredictable - the connections were sometimes removed correctly and sometimes some of them would persist (or even worse I was left with some one-way connections).
My complete code looks like this:
using UnityEngine;
using Unity.Collections;
using Pathfinding;
using Pathfinding.Jobs;
using Unity.Jobs;
using Unity.Burst;
[Pathfinding.Util.Preserve]
public class AStarThinWallsRule : GridGraphRule
{
public LayerMask ThinObstaclesLayerMask = 1 << 24;
public override void Register (GridGraphRules rules)
{
rules.Add(Pass.AfterConnections, context =>
{
var results = new NativeArray<RaycastHit>(context.data.nodePositions.Length * 8, Allocator.TempJob);
var commands = new NativeArray<RaycastCommand>(context.data.nodePositions.Length * 8, Allocator.TempJob);
var rayConnection = new NativeArray<bool>(context.data.nodePositions.Length * 8, Allocator.TempJob);
var size = context.data.bounds.size;
var nodeIndex = 0;
for (var y = 0; y < size.y; y++)
{
for (var z = 0; z < size.z; z++)
{
for (var x = 0; x < size.x; x++, nodeIndex++)
{
Vector3 origin = context.data.nodePositions[nodeIndex];
for (var i = 0; i < 8; i++)
{
rayConnection[(nodeIndex * 8) + i] = false;
var neighbourDataIndex = GetNeighbourDataIndex(context.data.bounds, context.data.nodeConnections, context.data.layeredDataLayout, nodeIndex, i);
var destination = context.data.nodePositions[neighbourDataIndex];
var direction = (destination - origin).normalized;
var length = (destination - origin).magnitude;
commands[(nodeIndex * 8) + i] = new RaycastCommand(origin, direction, length, ThinObstaclesLayerMask, 1);
}
}
}
}
JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(JobHandle));
handle.Complete();
for (var i = 0; i < results.Length; i++)
{
rayConnection[i] = results[i].collider != null;
}
new ThinWallsConnectionFilterJob {
bounds = context.data.bounds,
nodeConnections = context.data.nodeConnections,
layeredDataLayout = context.data.layeredDataLayout,
raycastConnections = rayConnection
}.Schedule(context.tracker);
results.Dispose();
commands.Dispose();
rayConnection.Dispose();
});
}
[BurstCompile]
struct ThinWallsConnectionFilterJob : IJob, IConnectionFilter {
public IntBounds bounds;
public NativeArray<int> nodeConnections;
[ReadOnly]
public NativeArray<bool> raycastConnections;
public bool layeredDataLayout;
public void Execute () {
FilterNodeConnections(bounds, nodeConnections, layeredDataLayout, ref this);
}
public bool IsValidConnection (int dataIndex, int dataX, int dataZ, int direction) {
return !raycastConnections[(dataIndex * 8) + direction];
}
}
}
I would really appreciate your help because I’m running out of ideas. I am able to prepare a full unity sample if that’s needed.