0

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 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 :

CheckDistanceToWaypoint(distance);

Line 67 is :

UpdateTargetWaypoint();

Line 81 is :

targetWaypoint = waypoints[targetWaypointIndex];

The complete script :

using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.AI;

public class Waypoints : UnityEngine.MonoBehaviour
{
    public List<Transform> waypoints = new List<Transform>();
    private Transform targetWaypoint;
    private int targetWaypointIndex = 0;
    private float minDistance = 0.1f; //If the distance between the enemy and the waypoint is less than this, then it has reacehd the waypoint
    private int lastWaypointIndex;

    private float movementSpeed = 5.0f;
    private float rotationSpeed = 2.0f;

    // Use this for initialization
    void Start()
    {
        var wps = GameObject.FindGameObjectsWithTag("Agent Waypoint");

        foreach(GameObject go in wps)
        {
            waypoints.Add(go.transform);
        }

        var teleporter = GameObject.Find("Pref_TransporterBlue");
        waypoints.Add(teleporter.transform);

        lastWaypointIndex = waypoints.Count - 1;
        targetWaypoint = waypoints[targetWaypointIndex]; //Set the first target waypoint at the start so the enemy starts moving towards a waypoint
    }

    // Update is called once per frame
    void Update()
    {
        if (targetWaypointIndex <= lastWaypointIndex)
        {
            float movementStep = movementSpeed * Time.deltaTime;
            float rotationStep = rotationSpeed * Time.deltaTime;

            Vector3 directionToTarget = targetWaypoint.position - transform.position;
            Quaternion rotationToTarget = Quaternion.LookRotation(directionToTarget);

            transform.rotation = Quaternion.Slerp(transform.rotation, rotationToTarget, rotationStep);

            Debug.DrawRay(transform.position, transform.forward * 50f, Color.green, 0f); //Draws a ray forward in the direction the enemy is facing
            Debug.DrawRay(transform.position, directionToTarget, Color.red, 0f); //Draws a ray in the direction of the current target waypoint

            float distance = Vector3.Distance(transform.position, targetWaypoint.position);
            CheckDistanceToWaypoint(distance);

            transform.position = Vector3.MoveTowards(transform.position, targetWaypoint.position, movementStep);
        }
    }

    /// <summary>
    /// Checks to see if the enemy is within distance of the waypoint. If it is, it called the UpdateTargetWaypoint function 
    /// </summary>
    /// <param name="currentDistance">The enemys current distance from the waypoint</param>
    void CheckDistanceToWaypoint(float currentDistance)
    {
        if (currentDistance <= minDistance)
        {
            targetWaypointIndex++;
            UpdateTargetWaypoint();
        }
    }

    /// <summary>
    /// 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)
    /// </summary>
    void UpdateTargetWaypoint()
    {
        if (targetWaypointIndex > lastWaypointIndex)
        {
            //targetWaypointIndex = 0;
        }

        targetWaypoint = waypoints[targetWaypointIndex];
    }
}

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 :

if (targetWaypointIndex <= lastWaypointIndex)

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.

ben dvivonim
  • 85
  • 1
  • 9
  • 1
    it probably comes from your `UpdateTargetWaypoint` ... something the error message would actually tell you and us if you added it – derHugo Jun 09 '20 at 07:44
  • You right I edited my question with the details. – ben dvivonim Jun 09 '20 at 10:54
  • You might want to consider not using a list, there's nothing wrong with it per se but a `LinkedList` might be better in this instance and you don't need to index into it and you can traverse backwards/forwards. The issue you have is simply that your index is going out of range of the list when you add one to your target waypoint index, you don't check if it's bigger than the list. Make sure you check if target index is equal to the number of items in the list, if it is, don't add one to it (unless you are looping then set it back to zero). Linked list would be better suited here though. – Charleh Jun 09 '20 at 11:42

0 Answers0