EDIT - Update the script and know am getting alot further but i get null reference at the last node for some reason… new path in Picture 3
Hey guys - Ive been working on my won pathfinding for a while now and got everything going great, i can build nodes, link them all together so each node knows its neighbour and its position and so on - not a problem but when trying to get a path i hit a wall, you see i can build a list of nodes from start to finish easy enough as shown in Picture 1 build getting a path using them nodes gives me a less then pleasing result as soon in Picture 2, i think the problem lies with GetClosestPath Function but not entirely sure neway ive posted my Seeker script below - any help would be much appreicted
~ Popper
Picture 1
Link - 2
Picture 2
Link - 4
Picture 3 - Pathfinding with new edit
Link - 6
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
public class PathNode
{
public Node Node;
public float Cost;
public PathNode(Node node, float distance_from_start, float distance_to_end)
{
Node = node;
Cost = distance_from_start + distance_to_end;
}
}
public class Seeker : MonoBehaviour
{
List<Node> Nodes = new List<Node>();
int NodeSpacing = 0;
List<Node> OpenList = new List<Node>();
List<Node> ClosedList = new List<Node>();
List<PathNode> OpenPath = new List<PathNode>();
List<PathNode> ClosedPathNodeList = new List<PathNode>();
public List<Vector3> SelectedPath = new List<Vector3>();
Node StartNode = null;
Node EndNode = null;
public List<Vector3> BuildPath(Vector3 Start, Vector3 End)
{
Stopwatch CodeTimer = new Stopwatch();
CodeTimer.Start();
ClearAll();
bool Failed = false;
Nodes = Pathfinding_Core.Nodes;
NodeSpacing = Pathfinding_Core.NodeSpacing;
StartNode = GetFirstNode(Start);
EndNode = GetFirstNode(End);
Node ParentNode = StartNode;
OpenList.Add(ParentNode);
while (ClosedList.Contains(EndNode) == false)
{
if (OpenList.Count == 0)
{
UnityEngine.Debug.Log("Broke out of building path...");
Failed = true;
break;
}
ParentNode = GetClosest(ParentNode, End);
}
UnityEngine.Debug.Log("Heusitc nodes - " + ClosedPathNodeList.Count);
if (Failed == false)
{
Node PathNode = EndNode;
OpenPath.Add(new PathNode(PathNode, 0, 0));
while (SelectedPath.Contains(StartNode.Position) == false)
{
if (OpenPath.Count == 0)
{
UnityEngine.Debug.Log("Broke out of getting path...");
UnityEngine.Debug.Log("Path count was at " + SelectedPath.Count + " nodes.");
//SelectedPath.Clear();
Failed = true;
break;
}
PathNode = GetClosestPath(PathNode, StartNode.Position);
if (PathNode != null)
{
SelectedPath.Add(PathNode.Position);
}
else
{
break;
}
}
if (Failed == false)
{
SelectedPath.Insert(0, End);
}
}
RemoveDuplicates();
SelectedPath.Reverse();
CodeTimer.Stop();
UnityEngine.Debug.Log("Complete in " + CodeTimer.ElapsedMilliseconds + "ms!");
return SelectedPath;
}
private Node GetClosest(Node Parent,Vector3 Destination)
{
foreach (var NewNode in Parent.Connections)
{
if ((OpenList.Contains(NewNode) == false) && (ClosedList.Contains(NewNode) == false))
{
OpenList.Add(NewNode);
}
}
float shortest = 99999999;
Node NodeToUse = null;
foreach (var OpenNode in OpenList)
{
float Distance = Vector3.Distance(OpenNode.Position, Destination);
if (Distance < shortest)
{
shortest = Distance;
NodeToUse = OpenNode;
}
}
ClosedPathNodeList.Add(new PathNode(NodeToUse, Vector3.Distance(NodeToUse.Position, StartNode.Position), Vector3.Distance(NodeToUse.Position, Destination)));
ClosedList.Add(NodeToUse);
OpenList.Remove(NodeToUse);
return NodeToUse;
}
private Node GetClosestPath(Node Parent, Vector3 Destination)
{
OpenPath.Clear();
foreach (var NewNode in ClosedPathNodeList)
{
if (Vector3.Distance(Parent.Position,NewNode.Node.Position) < (NodeSpacing * 1.9f))
{
if (NewNode.Node != EndNode)
{
OpenPath.Add(NewNode);
}
}
}
float shortest = float.MaxValue;
Node NodeToUse = null;
PathNode Node = null;
foreach (var OpenNode in OpenPath)
{
if (OpenNode.Cost < shortest)
{
shortest = OpenNode.Cost;
NodeToUse = OpenNode.Node;
Node = OpenNode;
}
}
ClosedPathNodeList.Remove(Node);
return NodeToUse;
}
private Node GetFirstNode(Vector3 Start)
{
float shortest = 99999999;
Node NodeToUse = null;
foreach (var Node in Nodes)
{
float Distance = Vector3.Distance(Node.Position, Start);
if (Distance < shortest)
{
shortest = Distance;
NodeToUse = Node;
}
}
return NodeToUse;
}
private void ClearAll()
{
SelectedPath.Clear();
ClosedPathNodeList.Clear();
OpenList.Clear();
ClosedList.Clear();
OpenPath.Clear();
}
private void RemoveDuplicates()
{
List<Vector3> NewList = new List<Vector3>();
foreach (var item in SelectedPath)
{
if (NewList.Contains(item) == false)
{
NewList.Add(item);
}
}
SelectedPath = NewList;
}
void OnDrawGizmos()
{
foreach (var opennode in OpenList)
{
Gizmos.color = Color.blue;
Gizmos.DrawSphere(opennode.Position, 0.1f);
}
foreach (var closednode in ClosedList)
{
Gizmos.color = Color.black;
Gizmos.DrawSphere(closednode.Position, 0.1f);
}
}
}