Array is out of range, but debug.log shows the correct value.

Hello, I am trying to make an infinite patrol script for some AI in my game, but I always get array out of range errors even though everything is set up correctly. I’ve read some topics and came to the conclusion that my array may not be initialized correctly, or something along those lines, but I don’t manage to find the exact problem.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PeasantWander : MonoBehaviour {
    public Transform[] PatrolPoints;
    public float Pause;
    public float MoveSpeed;
    [HideInInspector]
    public GameObject Peasant;
    [HideInInspector]
    public int CurrentIndex = 0;
 
    IEnumerator doPatrol()
    {
        yield return new WaitForSeconds(Pause);
        print(PatrolPoints.Length);
        Vector3.MoveTowards(Peasant.transform.position, PatrolPoints[CurrentIndex].position, MoveSpeed * Time.deltaTime);
    }
    void Start()
    {
        Peasant = this.gameObject;

    }
    void Update()
    {
        StartCoroutine(doPatrol());
    }
}

https://www.dropbox.com/s/s5wp9csrpr0iev1/Screenshot 2017-04-26 22.30.50.png?dl=0

I am not sure as to why you’re getting that error, but there is a problem with your code.
You should not be starting the CoRoutine in Update; this will begin many , many times per frame… and each one of those will wait a number of seconds and then progress… (you get the idea…)
Could be :30, 60, 90, 100+ times per second you’re firing this method off…

I would change that, for sure, to start… then come back and see what’s up.

If you’re getting an index out of range, it means you’re trying to call an index that doesn’t exist. How is CurrentIndex set?

And @methos5k already pointed out the issue with running coroutines from update.

Your array length is showing 0 in the image as well. Which means your array is empty, which is why you are getting the error since you can’t access index 0.

Err, I just realized… ya… it’s printing out zero, but there is 1 in the list. That doesn’t make sense.
Did you add that after it printed or something?

I got a bit lost in the title of your post:

Debug.Log is not showing the correct value (err, I mean not according to the screenshot info), but obviously the right number in the code.
It’s showing the Length of the array, and not the current index (my initial confusion).
In the screenshot, obviously the array length is ‘1’ … :slight_smile:

Edit again: After we get these several things sorted out, your MoveTowards is also not setup correctly. :slight_smile:

.Length returns how long the array is but you have to remember that arrays are zero based.

So if length returns 0 then your array is empty. If it returns 1 then you have a single item in the array which would be at index 0.

fixed the code, though still not able to figure out the error.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PeasantWander : MonoBehaviour {
    public Transform[] PatrolPoints;
    public float Pause;
    public float MoveSpeed;
    [HideInInspector]
    public GameObject Peasant;
    [HideInInspector]
    public int CurrentIndex = 0;
   
    IEnumerator doPatrol()
    {
        yield return new WaitForSeconds(Pause);
        print(PatrolPoints.Length);
        Peasant.transform.position= Vector3.MoveTowards(Peasant.transform.position, PatrolPoints[CurrentIndex].position, MoveSpeed * Time.deltaTime);
    }
    void Start()
    {
        Peasant = this.gameObject;
        StartCoroutine(doPatrol());
    }
   
}

Okay, 2 good fixes. I think there remains just 1 issue (unrelated exactly) but that unless you MoveTowards in 1 go, you will not make it all the way.

Now, back to your original issue. Do you assign at least 1 member to the array before you play?
And if so, does it still print out ‘0’ ?

I just tried checking if the length is printed out correctly, and oddly, no matter how many elements I have it does always print out 0, smh. Yes, I do assign atleast one/multiple members.

Mystery to me, sorry… :slight_smile:

I’m just a noob beginner, so if I’m wrong don’t fret to much about it, but shouldn’t there be a new assignment somewhere?

PatrolPoints = new Transform[ ]; or something like that?

1 Like

Because PatrolPoints is public and available in the inspector, this is not required. Unity will handle that for you. Which is why you add stuff through the inspector.

@Aardwing Do you only have one copy of the script in your scene?

That’s a good question; I was wondering if there were 2 copies, also.