In what sense? I don’t recall there being anything special I had to do. Are you using a pre-made pathfinding system or implementing your own?
I think I set up my node graph such that each node had a radius, and there were no obstructions between any two points in connected nodes. I made a function which got me the closest node to any given point in world space, possibly with some kind of obstruction check. To calculate a path I’d get the closest nodes to the start and end points and path between them with A*. When travelling along the path, as soon as the agent is within the radius of their current target node they pick a point within the radius of the following node and move towards that, until they reach the final node and head to their actual destination point (which should now be unobstructed).
I was using it to optimize, but I guess if I’m optimizing away a large portion of the nodes instead then no. I probably wouldn’t need the grid anymore I guess. Though everything is based on the grid and I’m reluctant to switch it all over.
I have a potential project I shelved because I realized I’d need to implement my own 3D pathfinding, but my general idea was an octree that subdivides whenever there is a potential collision. 2D example:
Each cell would contain its position, bounds, and a list of other connected cells. When a moving object detected that it would enter the same cell as another object, the cells would subdivide, updating their neighbor relationships, to a maximum of the larger object’s dimensions, until the moving object could pass through an empty cell.
The logic of subdividing would be trivially simple - pseudocode for a 2D example would be something like
public class Node
{
Vector2 pos;
Vector2 bounds;
List<Node> neighbors;
public Node(Vector2 center, Vector2 bounds)
{
this.pos = center;
this.bounds = bounds;
}
}
List<Node> nodes = new List<Node>();
...
sd = nodes[sdIndex];
var pos0 = new Vector2(sd.pos.x - (sd.bounds.x/2), sd.pos.y - (sd.bounds.y/2));
var pos1 = new Vector2(sd.pos.x - (sd.bounds.x/2), sd.pos.y + (sd.bounds.y/2));
var pos2 = new Vector2(sd.pos.x + (sd.bounds.x/2), sd.pos.y - (sd.bounds.y/2));
var pos3 = new Vector2(sd.pos.x + (sd.bounds.x/2), sd.pos.y + (sd.bounds.y/2));
var bounds = sd.bounds / 2;
List<Node> addNodes = new List<Node>
{
Node node0 = new Node(pos0, bounds),
Node node1 = new Node(pos1, bounds),
Node node2 = new Node(pos2, bounds),
Node node3 = new Node(pos3, bounds)
};
node0.neighbors.Add(node1);
node0.neighbors.Add(node2);
node1.neighbors.Add(node0);
node1.neighbors.Add(node3);
node2.neighbors.Add(node0);
node2.neighbors.Add(node3);
node3.neighbors.Add(node1);
node3.neighbors.Add(node2);
foreach(var neighbor in sd.neighbors)
{
neighbor.neighbors.Remove(sd);
List<float> distances = addNodes.Select(x => (x, Vector3.Distance(x.pos, neighbor.pos))).OrderBy(xx => xx.Item2).ToList();
neighbor.neighbors.Add(distances[0].Item1);
distances[0].Item1.neighbors.Add(neighbor);
neighbor.neighbors.Add(distances[1].Item1);
distances[1].Item1.neighbors.Add(neighbor);
}
nodes.RemoveAt(sd_index);
nodes.AddRange(addNodes);
I have no idea if this overall idea would work for pathfinding, or if there are way better solutions.