Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Getting exception ArgumentOutOfRangeException: Index was out of range. Must be non-negative

Discussion in 'Scripting' started by DubiDuboni, Jun 9, 2020.

  1. DubiDuboni

    DubiDuboni

    Joined:
    Feb 5, 2019
    Posts:
    131
    I'm trying to move a character between set of waypoints but getting exception :

    ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Reflection;
    5. using UnityEngine;
    6. using UnityEngine.AI;
    7.  
    8. public class Waypoints : UnityEngine.MonoBehaviour
    9. {
    10.    public List<Transform> waypoints = new List<Transform>();
    11.    private Transform targetWaypoint;
    12.    private int targetWaypointIndex = 0;
    13.    private float minDistance = 0.1f; //If the distance between the enemy and the waypoint is less than this, then it has reacehd the waypoint
    14.    private int lastWaypointIndex;
    15.  
    16.    private float movementSpeed = 5.0f;
    17.    private float rotationSpeed = 2.0f;
    18.  
    19.    // Use this for initialization
    20.    void Start()
    21.    {
    22.        var wps = GameObject.FindGameObjectsWithTag("Agent Waypoint");
    23.  
    24.        foreach(GameObject go in wps)
    25.        {
    26.            waypoints.Add(go.transform);
    27.        }
    28.  
    29.        var teleporter = GameObject.Find("Pref_TransporterBlue");
    30.        waypoints.Add(teleporter.transform);
    31.  
    32.        lastWaypointIndex = waypoints.Count - 1;
    33.        targetWaypoint = waypoints[targetWaypointIndex]; //Set the first target waypoint at the start so the enemy starts moving towards a waypoint
    34.    }
    35.  
    36.    // Update is called once per frame
    37.    void Update()
    38.    {
    39.        if (targetWaypointIndex <= lastWaypointIndex)
    40.        {
    41.            float movementStep = movementSpeed * Time.deltaTime;
    42.            float rotationStep = rotationSpeed * Time.deltaTime;
    43.  
    44.            Vector3 directionToTarget = targetWaypoint.position - transform.position;
    45.            Quaternion rotationToTarget = Quaternion.LookRotation(directionToTarget);
    46.  
    47.            transform.rotation = Quaternion.Slerp(transform.rotation, rotationToTarget, rotationStep);
    48.  
    49.            Debug.DrawRay(transform.position, transform.forward * 50f, Color.green, 0f); //Draws a ray forward in the direction the enemy is facing
    50.            Debug.DrawRay(transform.position, directionToTarget, Color.red, 0f); //Draws a ray in the direction of the current target waypoint
    51.  
    52.            float distance = Vector3.Distance(transform.position, targetWaypoint.position);
    53.            CheckDistanceToWaypoint(distance);
    54.  
    55.            transform.position = Vector3.MoveTowards(transform.position, targetWaypoint.position, movementStep);
    56.        }
    57.    }
    58.  
    59.    /// <summary>
    60.    /// Checks to see if the enemy is within distance of the waypoint. If it is, it called the UpdateTargetWaypoint function
    61.    /// </summary>
    62.    /// <param name="currentDistance">The enemys current distance from the waypoint</param>
    63.    void CheckDistanceToWaypoint(float currentDistance)
    64.    {
    65.        if (currentDistance <= minDistance)
    66.        {
    67.            targetWaypointIndex++;
    68.            UpdateTargetWaypoint();
    69.        }
    70.    }
    71.  
    72.    /// <summary>
    73.    /// Increaes the index of the target waypoint. If the enemy has reached the last waypoint in the waypoints list, it resets the targetWaypointIndex to the first waypoint in the list (causes the enemy to loop)
    74.    /// </summary>
    75.    void UpdateTargetWaypoint()
    76.    {
    77.        if (targetWaypointIndex > lastWaypointIndex)
    78.        {
    79.            //targetWaypointIndex = 0;
    80.        }
    81.  
    82.        targetWaypoint = waypoints[targetWaypointIndex];
    83.    }
    84. }
    85.  
    At the bottom I don't reset the variable targetWaypointIndex so it will not make a loop.

    And also I'm checking in the Update :

    Code (csharp):
    1.  
    2. if (targetWaypointIndex <= lastWaypointIndex)
    3.  
    So it will continue to move to the next waypoint/s only if it's less/equal but this IF check didn't solve the exception that keep throwing.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,151
    Always copy and paste the error as it gives a line number.

    Otherwise, my guess is line 82 might be the source of your error. But again, give the error with it's line number, debug the value you are passing into your collection along with the count and you should be able to figure out where it's going wrong.
     
    DubiDuboni likes this.
  3. DubiDuboni

    DubiDuboni

    Joined:
    Feb 5, 2019
    Posts:
    131
    ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
    System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <437ba245d8404784b9fbab9b439ac908>:0)
    System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <437ba245d8404784b9fbab9b439ac908>:0)
    System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <437ba245d8404784b9fbab9b439ac908>:0)
    Waypoints.UpdateTargetWaypoint () (at Assets/Scripts/Waypoints/Waypoints.cs:81)
    Waypoints.CheckDistanceToWaypoint (System.Single currentDistance) (at Assets/Scripts/Waypoints/Waypoints.cs:67)
    Waypoints.Update () (at Assets/Scripts/Waypoints/Waypoints.cs:52)


    Line 52 is :

    Code (csharp):
    1.  
    2. CheckDistanceToWaypoint(distance);
    3.  
    Line 67 is :

    Code (csharp):
    1.  
    2. UpdateTargetWaypoint();
    3.  
    Line 81 is :

    Code (csharp):
    1.  
    2. targetWaypoint = waypoints[targetWaypointIndex];
    3.  
     
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,151
    Yeah, so line 81 is the problem. It means targetWaypointIndex is not a value in range. You should debug the value and see what you are getting.

    I suspect the culprit is in your CheckDistanceToWaypoint() method which increments targetWaypointIndex without determining if it is within range of your waypoints collection.