ArgumentOutOfRangeException: Argument is out of range.

Hi,
I am making a text-base game with multiple choices (with the Ink plugin for Unity), and I am trying to trigger UI animations by reading the list “story.currentTags” which is a read only list of strings but I can’t figure out why I’m getting this error :

Blockquote

ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List`1[System.String].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
BasicInkExample.ChangerFond () (at Assets/Plugins/Ink/Example/Scripts/BasicInkExample.cs:113)
BasicInkExample.RefreshView () (at Assets/Plugins/Ink/Example/Scripts/BasicInkExample.cs:66)
BasicInkExample.StartStory () (at Assets/Plugins/Ink/Example/Scripts/BasicInkExample.cs:39)
BasicInkExample.Awake () (at Assets/Plugins/Ink/Example/Scripts/BasicInkExample.cs:33)

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using Ink.Runtime;

public class BasicInkExample : MonoBehaviour {
    public Animator anim;
    static string transitionTag = null;

    [SerializeField]
	private TextAsset inkJSONAsset;
	private Story story;
    private List<string> myTagString = new List<string>();
    //string transitionTag;

    [SerializeField]
	private Canvas canvas;

	// UI Prefabs
	[SerializeField]
	private Text textPrefab;
	[SerializeField]
	private Button buttonPrefab;

    void Start()
    {
        anim = FindObjectOfType<Animator>();
        //myTagString = story.currentTags;
    }

    void Awake () {
        StartStory();

    }

	void StartStory () {
		story = new Story (inkJSONAsset.text);
		RefreshView();
	}

    void RefreshView ()
    {
		RemoveChildren ();

        while (story.canContinue) {
			string text = story.Continue ().Trim();
			CreateContentView(text);
		}

        if (story.currentChoices.Count > 0) {
			for (int i = 0; i < story.currentChoices.Count; i++) {
				Choice choice = story.currentChoices *;*
  •  		Button button = CreateChoiceView (choice.text.Trim ());*
    
  •  		button.onClick.AddListener (delegate {*
    
  •  			OnClickChoiceButton (choice);*
    
  •  		});*
    
  •  	}*
    
  •  } else {*
    
  •  	Button choice = CreateChoiceView("End of story.
    

Restart?");*

  •  	choice.onClick.AddListener(delegate{*
    
  •  		StartStory();*
    
  •  	});*
    
  •  }*
    

ChangerFond();

}

void OnClickChoiceButton (Choice choice) {

  •  story.ChooseChoiceIndex (choice.index);*
    
  •  RefreshView();*
    
  • }*

  • void CreateContentView (string text) {*

  •  Text storyText = Instantiate (textPrefab) as Text;*
    
  •  storyText.text = text;*
    
  •  storyText.transform.SetParent (canvas.transform, false);*
    
  • }*

  • Button CreateChoiceView (string text) {*

  •  Button choice = Instantiate (buttonPrefab) as Button;*
    
  •  choice.transform.SetParent (canvas.transform, false);*
    
  •  Text choiceText = choice.GetComponentInChildren<Text> ();*
    
  •  choiceText.text = text;*
    
  •  HorizontalLayoutGroup layoutGroup = choice.GetComponent <HorizontalLayoutGroup> ();*
    
  •  layoutGroup.childForceExpandHeight = false;*
    
  •  return choice;*
    
  • }*

  • void RemoveChildren () {*

  •  int childCount = canvas.transform.childCount;*
    
  •  for (int i = childCount - 1; i >= 0; --i) {*
    
  •  	GameObject.Destroy (canvas.transform.GetChild (i).gameObject);*
    
  •  }*
    
  • }*

void ChangerFond()
{
int transition = 0;
//myTagString.RemoveAt(0);
myTagString = story.currentTags;

if (myTagString == null)
{
return;
}
else
{
transitionTag = myTagString[0];

if (transitionTag == “transition1”)
{
anim.SetTrigger(“Transition1”);
transition++;
}
else if (transitionTag == “transition2”)
{
anim.SetTrigger(“Transition2”);
transition++;
}
else if (transitionTag == “transition3”)
{
anim.SetTrigger(“Transition3”);
}
else
{
return;
}
}
}
}

It tells you “Error at […] BasicInkExample.cs:113) BasicInkExample.RefreshView”, so you go to line 113 of BasicInkExample.cs, where you see:

transitionTag = myTagString[0];

That means myTagString[0] gives you the error, which means myTagString index 0 is invalid, which means it doesn’t even have 1 element!

So you need to initialize myTagString array. That comes from story.currentTags;, and story comes from new Story(inkJSONAsset.text);. So possible issues:

  • story is not initialized properly, either because inkJSONAsset.text is null, or because the inkJSONAsset is unreadable, possibly is not assigned or does not exist

EDIT

  • story.currentTags is empty (you already checked for existence with if (story.currentTags == null) ): you need to check that it also has elements, i.e. if (story.currentTags.Count > 0)

Couldn’t you do

if (myTagString.Count == 0 || story.currentTags.Count == 0){
     return;
}

Thank you for your answer.

First, I can assure you that story is not the problem, because if I remove the function void ChangerFond()the error disappears and the game works perfectly fine. Actually the game works fine even with the error but without the feature I’m trying to add (UI animation).

And second, in my previous researches I saw that ArgumentOutOfRangeException is about reading an empty list. The problem is story.currentTagsis empty at the beginning of the game, and is filled with strings later, so what should I do to make the code not reading the list in the case it is empty ? I’ve tried this :

         if (myTagString == null)
         {
             return;
         }

but it’s not working.