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

public class wps : UnityEngine.MonoBehaviour
{
    public List<Transform> waypoints = new List<Transform>();
    public float speed = 2.0f;
    public bool faceHeading = true;
    public bool loop = false;

    private int index = 0; 

    // Use this for initialization
    protected void Start()
    {
        var ways = GameObject.FindGameObjectsWithTag("wp");
        foreach (GameObject go in ways)
        {
            waypoints.Add(go.transform);
        }
    }

    private void Update()
    {
        if(index != waypoints.Count)
        {
            transform.position = Vector3.MoveTowards(transform.position, waypoints[index].position, speed * Time.deltaTime);
        }

        if(transform.position == waypoints[index].position)
        {
            index++;
        }
    }
}

The object is getting to the last way point but then show the error ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index on line 33

if(transform.position == waypoints[index].position)
  • Your trying to access an index that does not exist (the index is out of range). I think what you're after is `if (index < waypoints.Count)`. If you have 33 items in an array, you can only access up to index 32 (as an array starts at position 0). When you get an exception it's usually very easy to find a good answer here on stack overflow, see this for more details: https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f – Binke Jun 09 '20 at 12:19
  • Does this answer your question? [What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?](https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f) – Liam Sep 28 '20 at 09:48

2 Answers2

0

The "problem" is you count 1,2,3 etc and the compiler 0,1,2 etc. To fix this you need to

if(transform.position == waypoints[index -1].position)

or

private int index = -1; 
Niklas
  • 172
  • 2
  • 8
0

Your code will increase index when reaching a waypoint. Even if that was already the last waypoint in the collection. You need to account for that in the index increase. It is not easy doing the index mechanics of a loop, if the loop is outside your control (like the game loop).

Solutions:

  • Maybe put the 2nd if inside the first?
  • A Stack or Queue might be a better tool for a waypoint system. It just depends wich end you start from.

Actually, even processing waypoints through a enumerator might work. They only go forward, you need no messy index and you get a simple checkable value for Next() (a false IIRC) when you hit the end:

//Create the class scope variable after filling the collection:
var waypointsEnumerator = waypoints.GetEnumerator();

Then just do this in Update:

if(waypointsEnumerator.MoveNext()){
    Transform currentWaypoint = waypointsEnumerator.Curent;
    //move to currentWaypoint here
}

It really depends what your final goal is. Teleporting between the waypoints seems like a early loop test at best.

One final warning: You are dealing with floats. Floats are not precise. Even after setting a float variable to a specific value, there is no guarantee it will match a == check!

Christopher
  • 8,956
  • 2
  • 14
  • 31