Search Unity

IndexOutOfRangeException: Array index is out of range? Someone knows what bug is..?

Discussion in 'Scripting' started by iiirwnsyh, Jun 27, 2019.

  1. iiirwnsyh

    iiirwnsyh

    Joined:
    Jan 14, 2018
    Posts:
    2
    I've been tested for a day. sometimes it run perfectly but sometimes it gaves me errors . But i guess, there is nothing wrong for code. What i did is this.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Unit : MonoBehaviour {
    6.  
    7.     public GameObject Abintang;
    8.     public Pathfinding pathfinding;
    9.  
    10.     public Transform target;
    11.     private float speed = 5;
    12.     private Vector3[] path;
    13.     private int targetIndex;
    14.     private bool checkSet;
    15.  
    16.  
    17.     public bool pathPending{
    18.         get{
    19.             return pathfinding.requestManager.isProcessingPath;
    20.             //return m_pathPending;
    21.         }
    22.     }
    23.  
    24.     public bool hasPath{
    25.         get{
    26.             //if (path.Length > 0) {
    27.             //    return true;
    28.             //} else {
    29.             //    return false;
    30.             //}
    31.             return pathfinding.m_hasPath;
    32.         }
    33.     }
    34.  
    35.     public Vector3 destination{
    36.         get{
    37.             if (pathfinding.requestManager.isProcessingPath){
    38.                 return pathfinding.m_destination;
    39.             }
    40.             if (path.Length == 0){
    41.                 return transform.position;
    42.             }
    43.             if (pathfinding.grid == null){
    44.                 return Vector3.positiveInfinity;
    45.             }
    46.             return pathfinding.m_destination;
    47.         }
    48.         set{
    49.             if (target != null) {
    50.                 pathfinding.m_destination = target.position;
    51.             }
    52.             pathfinding.m_destination = value;
    53.         }
    54.     }
    55.  
    56.     public float remainingDistance{
    57.         get{
    58.             if (pathfinding.m_destination != null){
    59.                 return Vector3.Distance( pathfinding.m_destination , transform.position );
    60.             }
    61.         }
    62.     }
    63.  
    64.  
    65.     public bool isStopped{
    66.         get{
    67.             return pathfinding.m_isStopped;
    68.         }
    69.         set{
    70.             pathfinding.m_isStopped = value;
    71.         }
    72.     }
    73.  
    74.     public float stoppingDistance {
    75.         get {
    76.             return pathfinding.m_stoppingDistance;
    77.         }
    78.         set {
    79.             if (isStopped) {
    80.                 pathfinding.m_stoppingDistance = Vector3.Distance (pathfinding.m_destination, transform.position);
    81.             }
    82.         }
    83.     }
    84.  
    85.     void Start(){
    86.         pathfinding = Abintang.GetComponent<Pathfinding> ();
    87.         //PathRequestManager.RequestPath (transform.position, target.position, OnPathFound);
    88.     }
    89.  
    90.     void Update(){
    91.         if (checkSet) {
    92.             PathRequestManager.RequestPath (transform.position, pathfinding.m_destination , OnPathFound);
    93.         }
    94.  
    95.  
    96.         if (target != null) {
    97.             if (Vector3.Distance (transform.position, target.position) > 1f) {
    98.                 SetDestination (target.position);
    99.             }
    100.         }
    101.  
    102.  
    103.         //print ("Distance = " + Vector3.Distance (transform.position, target.position).ToString ());
    104.  
    105.         //HasReachedDestination ();
    106.  
    107.         /*
    108.         if (Input.GetKeyDown(KeyCode.Space)){
    109.             //pathfinding.m_destination = target.position;
    110.             //PathRequestManager.RequestPath (transform.position, pathfinding.m_destination , OnPathFound);
    111.             SetDestination (target.position);
    112.             print ("target : " + target.position.ToString ());
    113.  
    114.             Debug.Log ("Pressed");
    115.         }*/
    116.     }
    117.  
    118.     public void OnPathFound(Vector3[] newPath,bool pathSuccessful){
    119.         if (pathSuccessful) {
    120.             path = newPath;
    121.             Debug.Log ("Path Length = " + path.Length.ToString ());
    122.             StopCoroutine ("FollowPath");
    123.             StartCoroutine ("FollowPath");
    124.         }
    125.     }
    126.  
    127.     IEnumerator FollowPath(){
    128.         Vector3 currentWaypoint = path [0];
    129.         targetIndex = 0;
    130.  
    131.         while (true) {
    132.             if (transform.position == currentWaypoint) {
    133.                 targetIndex++;
    134.                 Debug.Log ("Target Index = " + targetIndex.ToString ());
    135.                 if (targetIndex >= path.Length) {
    136.                     yield break;
    137.                 }
    138.                 currentWaypoint = path [targetIndex];
    139.             }
    140.             transform.LookAt (currentWaypoint);
    141.             print ("current waypoint : " + currentWaypoint.ToString ());
    142.             transform.position = Vector3.MoveTowards (transform.position, currentWaypoint, speed * Time.deltaTime);
    143.             checkSet = false;
    144.             //Debug.Log ("CheckSet = False");
    145.  
    146.             yield return null;
    147.         }
    148.     }
    149.  
    150.     public void OnDrawGizmos(){
    151.         if (path != null) {
    152.             for (int i = targetIndex; i < path.Length; i++) {
    153.                 Gizmos.color = Color.black;
    154.                 Gizmos.DrawCube (path , Vector3.one);
    155.  
    156.                 if (i == targetIndex) {
    157.                     Gizmos.DrawLine (transform.position, path );
    158.                 } else {
    159.                     Gizmos.DrawLine (path [i - 1], path );
    160.                 }
    161.             }
    162.         }
    163.     }
    164.  
    165.     public bool SetDestination( Vector3 _target){
    166.         if (_target != null) {
    167.             pathfinding.m_destination = _target;
    168.             checkSet = true;
    169.             Debug.Log ("CheckSet = true");
    170.             print ("SetDestination = " + _target.ToString());
    171.             return true;
    172.         } else {
    173.             checkSet = false;
    174.             return false;
    175.         }
    176.     }
    177.  
    178.     public void Stop(){
    179.         StopCoroutine ("FollowPath");
    180.         pathfinding.m_isStopped = true;
    181.     }
    182.  
    183.     public void Resume(){
    184.         PathRequestManager.RequestPath (transform.position, pathfinding.m_destination, OnPathFound);
    185.         //StopCoroutine ("FollowPath");
    186.         //StartCoroutine ("FollowPath");
    187.         pathfinding.m_isStopped = false;
    188.     }
    189.     public void HasReachedDestination(){
    190.         if (Vector3.Distance (transform.position, pathfinding.m_destination) < 0.10f) {
    191.             checkSet = false;
    192.             Debug.Log ("CheckSet = False");
    193.         }
    194.     }
    195.  
    196.     public void ResetPath(){
    197.         System.Array.Resize (ref path, 0);
    198.     }
    199. }
    And the error pointing to this line
    Code (CSharp):
    1. Vector3 currentWaypoint = path [0];
    Thanks.
     
    Last edited: Jun 27, 2019
  2. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    What this means is that you're asking for an element that doesn't exist in the array.
    For example imagine my array contains 3 elements and I try to use "myArray[4];". That's when you get this error.
    If it points to a line were you're using an array with an index of zero, your array may be empty or null. You probably haven't put any values. You may want to put a check like:
    Code (CSharp):
    1. if (path.Length == 0) {return;}
    or if should have something inside, recheck that you've filled the variable with an array that has an element inside. Like when you call "onPathFound", are you sure that the path you're putting has any element inside? You may need to fill the xyz values.
     
    Last edited: Jun 27, 2019
  3. iiirwnsyh

    iiirwnsyh

    Joined:
    Jan 14, 2018
    Posts:
    2
    i understand that. but in this case, the code sometimes run perfectly without any error like that. that made me confused and asked, why did the code error?
     
  4. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    425
    Sometimes it run prefectly because sometimes path do have some elements and sometimes it doesn't. When it doesn't, it throws this error. Just put the check I shared, and most probably you won't see the error again.
     
  5. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    I believe the problem exists outside of the code you posted here because of this
    Code (CSharp):
    1. public void OnPathFound(Vector3[] newPath,bool pathSuccessful){
    2.         if (pathSuccessful) {
    3.             path = newPath;
    4.             Debug.Log ("Path Length = " + path.Length.ToString ());
    5.             StopCoroutine ("FollowPath");
    6.             StartCoroutine ("FollowPath");
    7.         }
    8.     }
    Sometimes, your calling code passes in an empty array and pathSuccessful=true. That is causing the problem, I suspect.
     
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    There's two general kinds of code errors: compile errors and runtime errors.

    A compile error occurs when the computer reads your source code and translates it into machine language; in Unity, this happens automatically whenever the Unity editor has focus and detects that your source code has changed. For a given piece of source code, the compile errors are always the same, because they only depend on the code.

    A runtime error is something that the computer can't detect in advance, and only sees when it tries to actually run your code. The reason the computer can't detect it in advance is that it's somehow related to the circumstances in which your code is running (usually the data that it's operating on), which the compiler doesn't know in advance.

    The same thing that prevents the computer from predicting a runtime error also means that it might not happen every time. Since it depends on the circumstances when you run the code, if those circumstances change, the error might not happen.

    In this case, accessing path[0] is completely legal and allowed as long as path has an element #0. It only gives an error if path doesn't have an element #0. So the code will sometimes give an error, and sometimes not, depending on the value of path.

    One way to handle this is to make your code check whether path has any elements before you try to access one, and then take some different action if it doesn't. This strategy--where you check that your data fits the pattern you expect before you try to use it--is called defensive programming.

    Another way to handle it is to change the environment around your code so that path is guaranteed to have at least one element at all times (or at least at all the times when this function will get called).