Search Unity

While loop crashed the scene when set an element in Array line 60

Discussion in 'Scripting' started by genericdude98, May 15, 2020.

  1. genericdude98

    genericdude98

    Joined:
    Jan 2, 2020
    Posts:
    2
    Unity scene crashes if I set element node in the Array in the for loop.

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class GridManager : MonoBehaviour {
    5.  
    6.     public static GridManager s_Instance = null; // static = attached to class only
    7.     // static also means that all instantiations of the class will have this var // ignores the variable
    8.  
    9.     public static GridManager Instance // this is a property
    10.     {
    11.         get
    12.         {
    13.             if (s_Instance == null)
    14.             {
    15.                 s_Instance = FindObjectOfType(typeof(GridManager)) as GridManager;
    16.  
    17.                 if (s_Instance == null)
    18.                 {  // if sinstance is still null
    19.                     Debug.Log("No grid Manager");
    20.  
    21.                 }
    22.  
    23.             }
    24.             return s_Instance;
    25.         }
    26.  
    27.     }
    28.  
    29.  
    30.  
    31.     public int numOfRows = 10;
    32.     public int numOfColumns = 10;
    33.     public float cellSize = 1;
    34.     public bool showGrid = true;
    35.     public bool showObstacleBlocks = true;
    36.  
    37.  
    38.  
    39.     private Vector3 origin = new Vector3();
    40.     private GameObject[] obstacleList;
    41.     public Node[,] nodes { get; set; } // property so it can be retrieved
    42.     public Vector3 Origin { get { return origin; } } // property for origin
    43.  
    44.      public void Awake()
    45.     {
    46.         obstacleList = GameObject.FindGameObjectsWithTag("Obstacle");
    47.  
    48.  
    49.         CalculateObstacles();// method...
    50.  
    51.      
    52.     }
    53.  
    54.     void CalculateObstacles()
    55.     {
    56.         nodes = new Node[numOfColumns, numOfRows]; // the general array that contains everything
    57.         int index = 0;
    58.  
    59.         int i = 0;
    60.         while ( i < numOfColumns)
    61.         {
    62.             int j = 0;
    63.             while(j< numOfRows)
    64.             {
    65.                 Vector3 cellPos = GetGridCellCentre(index);// look helper methods
    66.                 Node node = new Node(cellPos); // with v3
    67.                 Debug.Log(node.position);
    68.                 Debug.Log(nodes);
    69.                 Debug.Log(i + " " + j);
    70.  
    71.                 nodes[i, j] = node;
    72.            
    73.                
    74.                 // putting in array with v3 positions //
    75.                 //the node part crashes the loop
    76.  
    77.                
    78.  
    79.                 index++;
    80.  
    81.                 j++;
    82.  
    83.             }
    84.                 i++;
    85.         }
    86.  
    87.  
    88.  
    89.         if (obstacleList != null && obstacleList.Length > 0)
    90.         {
    91.  
    92.  
    93.             foreach (GameObject data in obstacleList)
    94.             {
    95.  
    96.                 int indexCell = GetGridIndex(data.transform.position);
    97.                 int col = GetColumn(indexCell); // get pos and therefore col and row
    98.                 int row = GetRow(indexCell); // then mark as obstacle
    99.                 nodes[row, col].MarkAsObstacle();
    100.  
    101.                 // crashed the system if put outside loop or eliminated---
    102.  
    103.             }
    104.  
    105.         }
    106.     }
    107.  
    108.  
    109.  
    110.     void AssignNeighbours(int row, int col, ArrayList neighbours)
    111.     {
    112.  
    113.         if (row != -1 && col != -1 && col < numOfColumns && row < numOfRows) // as to not go out of grid
    114.         {
    115.  
    116.             Node nodesToAdd = nodes[row, col];
    117.             if (!nodesToAdd.bObstacle) // this is a bool in the node class
    118.             {
    119.                 neighbours.Add(nodesToAdd);
    120.             }
    121.  
    122.         }
    123.  
    124.  
    125.     }
    126.  
    127.     public void GetNeighbours(Node node, ArrayList neighbors) {
    128.         Vector3 neighborPos = node.position;
    129.         int neighborIndex = GetGridIndex(neighborPos);
    130.         int row = GetRow(neighborIndex);
    131.         int col = GetColumn(neighborIndex);
    132.            
    133.         // bottom
    134.         int downRow = row - 1;
    135.         int downCol = col;
    136.         AssignNeighbours(downRow, downCol, neighbors);
    137.         //up
    138.         int upRow = row + 1;
    139.         int upCol = col;
    140.         AssignNeighbours(upRow, upCol, neighbors);
    141.         //left
    142.         int leftRow = row;
    143.         int leftCol = col - 1;
    144.         AssignNeighbours(leftRow, leftCol, neighbors);
    145.         //right
    146.         int rightRow = row;
    147.         int rightCol = col + 1;
    148.         AssignNeighbours(rightRow, rightCol, neighbors);
    149.  
    150.  
    151.     }
    152.  
    153.  
    154.  
    155.     public void OnDrawGizmos()
    156.     {
    157.         if (showGrid)
    158.         {
    159.             DebugDrawGrid(transform.position, numOfRows, numOfColumns, cellSize, Color.blue);
    160.  
    161.         }
    162.  
    163.         Gizmos.DrawSphere(transform.position, .5f);
    164.  
    165.  
    166.  
    167.         if (showObstacleBlocks) {
    168.             Vector3 obstacleCellSize = new Vector3(cellSize , 1.0f, cellSize);
    169.             if (obstacleList != null && obstacleList.Length > 0) {
    170.                 foreach (GameObject data in obstacleList) {
    171.  
    172.                     int index = GetGridIndex(data.transform.position);
    173.                 Gizmos.DrawCube(GetGridCellCentre(index), obstacleCellSize);
    174.                
    175.                 }
    176.            
    177.             }
    178.        
    179.         }
    180.  
    181.      
    182.     }
    183.  
    184.     private void DebugDrawGrid(Vector3 origin, int numRows, int numCols, float cellSize, Color color)
    185.     {
    186.         float width = numCols * cellSize;
    187.         float height = numRows * cellSize;
    188.  
    189.         for (int i = 0; i < numRows + 1; i++) // loop to go through all of the rows!!!!
    190.         {
    191.             Vector3 startPos = origin + i * cellSize * Vector3.forward;
    192.             Vector3 endPos = startPos + width * Vector3.right;
    193.  
    194.             Debug.DrawLine(startPos, endPos, color);
    195.         }
    196.  
    197.         for (int i = 0; i < numCols + 1; i++)
    198.         {
    199.             Vector3 startPos = origin + i * cellSize * Vector3.right;
    200.             Vector3 endPos = startPos + height * cellSize * Vector3.forward;
    201.  
    202.             Debug.DrawLine(startPos, endPos, color);
    203.         }
    204.  
    205.     }
    206.  
    207.  
    208.  
    209.     public Vector3 GetGridCellCentre(int index)
    210.     {
    211.  
    212.         Vector3 cellPosition = GetGridCellPosition(index);
    213.         cellPosition.x += (cellSize / 2);
    214.         cellPosition.z += (cellSize / 2);
    215.         return cellPosition;
    216.  
    217.     }
    218.  
    219.  
    220.     public Vector3 GetGridCellPosition(int index)
    221.     {
    222.         int row = GetRow(index);
    223.         int column = GetColumn(index);
    224.         float xPosInGrid = column * cellSize;
    225.         float zPosInGrid = row * cellSize;
    226.         return Origin + new Vector3(xPosInGrid, 0.0f, zPosInGrid);
    227.  
    228.     }
    229.  
    230.     public int GetRow(int index)
    231.     {
    232.         int row = index / numOfColumns;
    233.         return row;
    234.     }
    235.  
    236.     public int GetColumn(int index)
    237.     {
    238.         int col = index % numOfColumns;
    239.         return col;
    240.  
    241.     }
    242.  
    243.  
    244.     public int GetGridIndex(Vector3 pos)
    245.     {
    246.  
    247.         if (!isInBound(pos)) {
    248.             return -1;
    249.        
    250.         }
    251.  
    252.         pos -= Origin; ;
    253.         int col = (int)(pos.x / cellSize);// get the num of column  // why (int) // it returns int even if float type
    254.         int row = (int)(pos.z / cellSize); // get num of row
    255.         return (row * numOfRows + col); // return the index
    256.  
    257.     }
    258.  
    259.  
    260.     public bool isInBound(Vector3 pos)
    261.    
    262.     {
    263.         float width = numOfColumns * cellSize;
    264.         float height = numOfRows * cellSize;
    265.         return (pos.x >= Origin.x && pos.x <= Origin.x + width &&
    266.             pos.z >= Origin.z && pos.z <= Origin.z + height);
    267.  
    268.  
    269.     }
    270. }
    271.  
    272.  
    The code is an implementation of A* pathfinding for Unity as in the book Unity 4.x Game AI Programming by Aung Sithu Kyaw. Can't implement in my scene.
     

    Attached Files:

  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    A lot of code here. You have error logs and line numbers? Can you describe what you mean by crash? Does the unity editor crash? Does it freeze?
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,695
    It's likely some endless loop due to a degenerate loop exit condition.

    Put a separate counter in and don't let the loop continue past some number of iterations, such as 100,000 iterations. If it exits, then your exit conditions are wrong in some way, or perhaps work done inside the loop is extending the exit conditions, which will continue until you run out of RAM.
     
    Vryken likes this.
  4. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    To expand on what Kurt-Dekker stated, wherever you have your while-loop, add something like this to it:
    Code (CSharp):
    1. void SomeMethod() {
    2.    int loopCount = 0;
    3.  
    4.    while(/* some condition */) {
    5.       //Do your regular logic...
    6.  
    7.       loopCount++;
    8.  
    9.       if(loopCount > 100000) {
    10.          Debug.LogError("Infinite loop created", this);
    11.          break;
    12.       }
    13.    }
    14. }
    After that, then try debugging the cause of the infinite loop in your while-loop logic.
     
    Kurt-Dekker likes this.
  5. genericdude98

    genericdude98

    Joined:
    Jan 2, 2020
    Posts:
    2

    Thank you for your reply. The problem is that whenever I hit play mode the whole window freezes and have to force quit.
    What I figured out is that <the nodes[i, j] = node;> is somehow causing the infinite loop. If I remove = node; and put something like Debug.Log(nodes) works without looping.