Shows a simple graph type generating a polar graph.
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
using Pathfinding.Serialization;
using Pathfinding.Util;
[JsonOptIn]
public class PolarGraph : NavGraph {
[JsonMember]
public int circles = 10;
[JsonMember]
public int steps = 20;
[JsonMember]
public Vector3 center = Vector3.zero;
[JsonMember]
public float scale = 2;
public PointNode[] nodes;
GraphTransform transform;
PointNode CreateNode (Vector3 position) {
var node = new PointNode(active);
node.position = (Int3)position;
return node;
}
static Vector3 CalculateNodePosition (int circle, float angle, GraphTransform transform) {
var pos = new Vector3(Mathf.Sin(angle), 0, Mathf.Cos(angle));
pos *= circle;
pos = transform.Transform(pos);
return pos;
}
protected override IEnumerable<Progress> ScanInternal () {
PointNode[][] circleNodes = new PointNode[circles][];
transform = new GraphTransform(Matrix4x4.TRS(center, Quaternion.identity, Vector3.one*scale));
circleNodes[0] = new PointNode[] {
CreateNode(CalculateNodePosition(0, 0, transform))
};
float anglesPerStep = (2*Mathf.PI)/steps;
for (int circle = 1; circle < circles; circle++) {
circleNodes[circle] = new PointNode[steps];
for (int step = 0; step < steps; step++) {
float angle = step * anglesPerStep;
Vector3 pos = CalculateNodePosition(circle, angle, transform);
circleNodes[circle][step] = CreateNode(pos);
}
}
for (int circle = 1; circle < circles; circle++) {
for (int step = 0; step < steps; step++) {
PointNode node = circleNodes[circle][step];
int numConnections = circle < circles-1 ? 4 : 3;
var connections = new Connection[numConnections];
connections[0].node = circleNodes[circle][(step+1) % steps];
connections[1].node = circleNodes[circle][(step-1+steps) % steps];
if (circle > 1) {
connections[2].node = circleNodes[circle-1][step];
} else {
connections[2].node = circleNodes[circle-1][0];
}
if (numConnections == 4) {
connections[3].node = circleNodes[circle+1][step];
}
for (int q = 0; q < connections.Length; q++) {
connections[q].cost = (uint)(node.position-connections[q].node.position).costMagnitude;
}
node.connections = connections;
}
}
PointNode centerNode = circleNodes[0][0];
centerNode.connections = new Connection[steps];
for (int step = 0; step < steps; step++) {
centerNode.connections[step] = new Connection(
circleNodes[1][step],
(uint)(centerNode.position-circleNodes[1][step].position).costMagnitude
);
}
List<PointNode> allNodes = new List<PointNode>();
for (int i = 0; i < circleNodes.Length; i++) {
allNodes.AddRange(circleNodes[i]);
}
nodes = allNodes.ToArray();
for (int i = 0; i < nodes.Length; i++) {
nodes[i].Walkable = true;
}
yield break;
}
public override void GetNodes (System.Action<GraphNode> action) {
if (nodes == null) return;
for (int i = 0; i < nodes.Length; i++) {
action(nodes[i]);
}
}
}