Unity crashing due to error in script fo AI.
I have been following a tutorial for AI scripting but from this point https://www.youtube.com/watch?v=3Dw5d7PlcTM#t=23m44s he makes a few minor changes to the script which should streamline the AI but instead it causes unity to crash. Looking online it may have to do with the "while" causing an endless loop but I am not sure. Thanks for the help looking into this.
Below is the script which run fine but is not streamlined. using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Diagnostics;
public class Pathfinding : MonoBehaviour {
public Transform seeker, target;
Grid grid;
void Awake() {
grid = GetComponent<Grid> ();
}
void Update(){
if (Input.GetButtonDown ("Jump")) {
FindPath (seeker.position, target.position);
}
}
void FindPath(Vector3 startPos, Vector3 targetPos) {
Stopwatch sw = new Stopwatch ();
sw.Start ();
Node starNode = grid.NodeFromWorldPoint (startPos);
Node targetNode = grid.NodeFromWorldPoint (targetPos);
List<Node> openSet = new List<Node> ();
HashSet<Node> closedSet = new HashSet<Node> ();
openSet.Add (starNode);
while (openSet.Count > 0) {
Node currentNode = openSet [0];
for (int i = 1; i < openSet.Count; i ++) {
if (openSet [i].fCost < currentNode.fCost || openSet [i].fCost == currentNode.fCost && openSet [i].hCost < currentNode.hCost) {
currentNode = openSet [i];
}
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
if (currentNode == targetNode) {
sw.Stop ();
print ("Path found: " + sw.ElapsedMilliseconds + " ms");
RetracePath(starNode,targetNode);
return;
}
foreach (Node neighbour in grid.GetNeighbours(currentNode)) {
if (!neighbour.walkable || closedSet.Contains(neighbour)) {
continue;
}
int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) {
neighbour.gCost = newMovementCostToNeighbour;
neighbour.hCost = GetDistance (neighbour, targetNode);
neighbour.parent = currentNode;
if (!openSet.Contains (neighbour))
openSet.Add (neighbour);
}
}
}
}
void RetracePath(Node startNode, Node endNode) {
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode) {
path.Add(currentNode);
currentNode = currentNode.parent;
}
path.Reverse();
grid.path = path;
}
int GetDistance(Node nodeA, Node nodeB){
int dstX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
int dstY = Mathf.Abs(nodeA.gridY - nodeB.gridY);
if (dstX > dstY)
return 14*dstY + 10* (dstX-dstY);
return 14*dstX + 10 * (dstY-dstX);
}
}
And below is the streamlined script which crashes unity and I have to shutdown unity using the task manager.
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Diagnostics;
public class Pathfinding : MonoBehaviour {
public Transform seeker, target;
Grid grid;
void Awake() {
grid = GetComponent<Grid> ();
}
void Update(){
if (Input.GetButtonDown ("Jump")) {
FindPath (seeker.position, target.position);
}
}
void FindPath(Vector3 startPos, Vector3 targetPos) {
Stopwatch sw = new Stopwatch ();
sw.Start ();
Node starNode = grid.NodeFromWorldPoint (startPos);
Node targetNode = grid.NodeFromWorldPoint (targetPos);
Heap<Node> openSet = new Heap<Node> (grid.MaxSize);
HashSet<Node> closedSet = new HashSet<Node> ();
openSet.Add (starNode);
while (openSet.Count > 0) {
Node currentNode = openSet.RemoveFirst();
closedSet.Add(currentNode);
if (currentNode == targetNode) {
sw.Stop ();
print ("Path found: " + sw.ElapsedMilliseconds + " ms");
RetracePath(starNode,targetNode);
return;
}
foreach (Node neighbour in grid.GetNeighbours(currentNode)) {
if (!neighbour.walkable || closedSet.Contains(neighbour)) {
continue;
}
int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) {
neighbour.gCost = newMovementCostToNeighbour;
neighbour.hCost = GetDistance (neighbour, targetNode);
neighbour.parent = currentNode;
if (!openSet.Contains (neighbour))
openSet.Add (neighbour);
else {
openSet.UpdateItem (neighbour);
}
}
}
}
}
void RetracePath(Node startNode, Node endNode) {
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode) {
path.Add(currentNode);
currentNode = currentNode.parent;
}
path.Reverse();
grid.path = path;
}
int GetDistance(Node nodeA, Node nodeB){
int dstX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
int dstY = Mathf.Abs(nodeA.gridY - nodeB.gridY);
if (dstX > dstY)
return 14*dstY + 10* (dstX-dstY);
return 14*dstX + 10 * (dstY-dstX);
}
}
The changes made to the script that works to make it into the script that does not is Line 27 (List changed to Heap as well as a few words added to the line.) Deleted lines 33-38 and made a small change to the end of line 32. Line 62 added "else" and line 63 added - openSet.UpdateItem(neighbour);
Update:
The changes made to the script that works to make it into the script that does not is Line 20 (List changed to Heap as well as a few words added to the line.) Deleted lines 26-31 and made a small change to the end of line 25. Line 53 added "else" and line 54 added - openSet.UpdateItem(neighbour);