IndexOutOfRangeException and not sure why?

I’m getting the classic error, but I’m not sure why.

IndexOutOfRangeException: Index was outside the bounds of the array.
Dialogue.Update () (at Assets/Scripts/Hub World/Dialogue.cs:57)

What could I be doing wrong here? Script below:

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

public class Dialogue : MonoBehaviour
{
    public string[] dialogueLine, dialogueLineB, dialogueLineC;
    //public Collider2D dCollider;

    private int dCounter;
    private bool canTalk;
    private int dialogueSelection, dialogueRangeHigh;

    public int dialogueStartSound, dialogueStopSound, dialogueSound;


    // Start is called before the first frame update
    void Start()
    {
        if (dialogueLineC != null)
        {
            dialogueRangeHigh = 3;
        }

        if (dialogueLineB != null)
        {
            dialogueRangeHigh = 2;
        }

        if (dialogueLine != null)
        {
            dialogueRangeHigh = 1;
        }


        dialogueSelection = Random.Range(0, dialogueRangeHigh);




        dCounter = 0;
        canTalk = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (canTalk && (PlayerController.instance.player.GetButtonUp("Fire") || PlayerController.instance.player.GetButtonUp("Dodge")) && DialogueManager.instance.isChatting)
        {
            dCounter++;

            if (DialogueManager.instance.isChatting)
            {

                if (dialogueSelection == 0)
                {
                    DialogueManager.instance.dialogueText.text = dialogueLine[dCounter];
                }
                if (dialogueSelection == 1)
                {
                    DialogueManager.instance.dialogueText.text = dialogueLineB[dCounter];
                }
                if (dialogueSelection == 2)
                {
                    DialogueManager.instance.dialogueText.text = dialogueLineC[dCounter];
                }
            }

            AudioManager.instance.PlaySFX(dialogueSound);

        }

        if (PlayerController.instance.player.GetButtonUp("Cancel")  && DialogueManager.instance.isChatting)
        {
            dCounter = dialogueLine.Length;

            if (dialogueSelection == 0)
            {
                dCounter = dialogueLine.Length;
            }
            if (dialogueSelection == 1)
            {
                dCounter = dialogueLineB.Length;
            }
            if (dialogueSelection == 2)
            {
                dCounter = dialogueLineC.Length;
            }
        }

        if (dCounter > dialogueLine.Length - 1 && DialogueManager.instance.isChatting)
        {
            AudioManager.instance.PlaySFX(dialogueStopSound);
            DialogueManager.instance.isChatting = false;
            DialogueManager.instance.dialogueContainer.SetActive(false);
            dCounter = 0;
            canTalk = false;
            //Time.timeScale = 1f;
            PlayerController.instance.canWalk = true;

            if (!PlayerController.instance.isHub)
            {
                PlayerController.instance.cannotDodge = false;
                PlayerController.instance.rangedArm.SetActive(true);
                PlayerController.instance.meleeArm.SetActive(true);
            }

        }

        //Debug.Log("dCounter = " + dCounter);
        //Debug.Log(dialogueLine.Length);

    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Player")
        {
            AudioManager.instance.PlaySFX(dialogueStartSound);
            DialogueManager.instance.isChatting = true;

            if (dialogueSelection == 0)
            {
                DialogueManager.instance.dialogueText.text = dialogueLine[dCounter];
            }
            if (dialogueSelection == 1)
            {
                DialogueManager.instance.dialogueText.text = dialogueLineB[dCounter];
            }
            if (dialogueSelection == 2)
            {
                DialogueManager.instance.dialogueText.text = dialogueLineC[dCounter];
            }

            //HubUIController.instance.DisplayDialogue();
            DialogueManager.instance.dialogueContainer.SetActive(true);
           

            //Time.timeScale = 0f;
            PlayerController.instance.canWalk = false;
            PlayerController.instance.cannotDodge = true;
            PlayerController.instance.rangedArm.SetActive(false);
           
            PlayerController.instance.meleeArm.SetActive(false);
            //PlayerController.instance.meleeArm.SetActive(false);


            canTalk = true;

            /*GameObject[] allFX = GameObject.FindGameObjectsWithTag("FX");

            for (int i = 0; i < allFX.Length; i++)
            {
                allFX[i].SetActive(false);
            }*/


            /*if (Input.anyKeyDown)
            {
                Debug.Log("next line");
                dCounter++;
            }*/
        }
    }
}

Presumably because the dCounter is outside the index of dialogueLine. I can see you’re always incrementing it in Update before you use it. Probably should check if its within the bounds of the array before using it.

Well it’s happening because dCounter is outside of the range of dialogueLine which is accessed at line 57.

How it gets out of range… well considering you modify the length of dCounter in various ways via incrementers (++) as well as just straight up setting it to dialogueLine.Length in other places (see: line 75). And you don’t do any tests to see if it’s NOT outside the range of dialogueLine… well that’s bound to happen.

For example if one enters the trigger2d, which sets canTalk true and isChatting true, then press cancel while still in the trigger setting dCounter to dialogueLine.Length, and then presses dodge/fire. Welp, dCounter is now at dialogueLine.Length which is out of the range when it enters the if statement and hits line 57 (since range is 0->len-1).

As to why your logic is like this… :shrug:, that’s up to you. I have no idea what you’re actually trying to do with your logic here. But clearly it doesn’t work the way you expect it to.

I’m late to the party behind Spiney and Duct, but for completeness I’ll just leave this here:

Here are some notes on IndexOutOfRangeException and ArgumentOutOfRangeException:

http://plbm.com/?p=236

Steps to success:

  • find which collection it is (critical first step!)
  • find out why it has fewer items than you expect
  • fix whatever logic is making the indexing value exceed the collection
  • remember you might have more than one instance of this script in your scene/prefab

This was helpful, thank you! I was able to resolve this by -1 from dCounter. Maybe not the coolest logic but it’s working.