c# Argument Out Of Range

I am trying to save several instances of a class in a Generic List. I am assigning game objects to the gameobject list in the inspector and grabbing the sheet script from each of them and putting those into another list that will be saved. I keep getting an “ArgumentOutOfRangeException: Argument is out of range. Parameter name: index” Error and I am not sure why.

public class CharacterManager : MonoBehaviour
{
    public static CharacterManager characterManager;
   
    void Awake () {
        if (characterManager == null) {
            characterManager = this;
            DontDestroyOnLoad (gameObject);
        }else if(characterManager != this){
            Destroy(gameObject);
        }
    }

    public List<GameObject> CharactersSaveAndLoad = new List<GameObject>(1);
    private List<CharacterSheet> CharacterSheetsSaveAndLoad = new List<CharacterSheet>(1);

    public void GetSheets(){
        for (int i = 0; i < 10; i++) {
            CharacterSheetsSaveAndLoad[i] = CharactersSaveAndLoad[i].GetComponent<CharacterSheet>();
        }
    }
    public void Save(){
        BinaryFormatter bf = new BinaryFormatter ();
        FileStream file = File.Create (Application.persistentDataPath + "/playerInfo.dat");

        GetSheets ();
        CharacterData data = new CharacterData ();

        data.Sheets = CharacterSheetsSaveAndLoad;
       
        bf.Serialize (file, data);
        file.Close();
        Debug.Log ("Save Compleated");
       
    }
    public void Load(){

    }
}

//[serializable]
public class CharacterData{
    public List<CharacterSheet> Sheets;
}

Avoid using fixed values for the loops.
A List provides a property named ‘Count’, use that for the loops condition.
In order to fill the other List, do not use the indexer ( ) in this case, it’s better to use the Add method unless you need to re-assign some specific entries. But then you have to make sure that the list has at least n+1 entries, if you want to assign the element with index n.

If I use Add, do I have to clear the list before saving again or does it overwrite if whatever is being added already exists?

I fixed it and it now saves but I have come across another problem when trying to load back to the object.
I have this in the awake method of the sheet on an object.

void Awake(){
        CharacterManager.Load(this.gameObject);
    }

and this is my load method in the manager.

public void Load(GameObject CharacterObject){
        CharacterSheet objectCharacterSheet = CharacterObject.GetComponent<CharacterSheet>();
        CharacterSheet findCharacterSheet;

        if (File.Exists (Application.persistentDataPath + "/playerInfo.dat")) {
            BinaryFormatter bf = new BinaryFormatter ();
            FileStream file = File.Open (Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
            CharacterData data = (CharacterData)bf.Deserialize(file);
            file.Close();

            for (int i = 0; i < data.Sheets.Count; i++){
                if (data.Sheets[i].objectID == objectCharacterSheet.objectID){
                    findCharacterSheet = data.Sheets[i];
                }
            }
            objectCharacterSheet.characterName = findCharacterSheet.characterName;
        }
    }

I keep getting an error when I try to call load from my charactersheet. I believe that it wants the gameobject reference to be static but it cant.

What’s the error?
You should also catch possible exceptions and handle them properly, especially when dealing with IO.

Assets/_Scripts/Characters/CharacterSheets/CharacterSheet.cs(45,34): error CS0120: An object reference is required to access non-static member `CharacterManager.Load(CharacterSheet)’

I think I fixed the problem but now I have an issue with serialization. when I put an object in the list of gameobject for saving, it says the character sheet is not marked as serializable. I think okay i’ll just put [System.Serializable] at the top of the script and see what happens. It then proceeds to give me another error saying that the script that the sheet inherits from isn’t marked so I put [System.Serializable] at the top of that and test it. finally it gives me the error that monobehavior is not marked. I know that if I were to somehow serialize monobehaviour I would end up with huge save files and that seems counter productive. I probably doing something wrong so some help would be appreciated.

My Revised Script:

public class CharacterManager : MonoBehaviour
{
    public static CharacterManager characterManager;
   
    void Awake () {
        if (characterManager == null) {
            characterManager = this;
            DontDestroyOnLoad (gameObject);
        }else if(characterManager != this){
            Destroy(gameObject);
        }
    }

    public List<GameObject> CharactersSaveAndLoad = new List<GameObject>(2);
    private List<CharacterSheet> CharacterSheetsSaveAndLoad = new List<CharacterSheet>(2);

    public void GetSheets(){
        CharacterSheetsSaveAndLoad.Clear();
        for (int i = 0; i < CharactersSaveAndLoad.Count; i++) {
            CharacterSheetsSaveAndLoad.Add (CharactersSaveAndLoad[i].GetComponent<CharacterSheet>());
        }
    }
    public void Save(){
        BinaryFormatter bf = new BinaryFormatter ();
        FileStream file = File.Create (Application.persistentDataPath + "/playerInfo.dat");

        GetSheets ();
        CharacterData data = new CharacterData ();

        data.Sheets = CharacterSheetsSaveAndLoad;
       
        bf.Serialize (file, data);
        file.Close();
        Debug.Log ("Save Compleated");
       
    }
    public static void Load(GameObject CharacterObject){
        CharacterSheet objectCharacterSheet = CharacterObject.GetComponent<CharacterSheet>();
        //CharacterSheet findCharacterSheet = CharacterObject.GetComponent<CharacterSheet>();

        if (File.Exists (Application.persistentDataPath + "/playerInfo.dat")) {
            BinaryFormatter bf = new BinaryFormatter ();
            FileStream file = File.Open (Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
            CharacterData data = (CharacterData)bf.Deserialize(file);
            file.Close();

            for (int i = 0; i < data.Sheets.Count; i++){
                if (data.Sheets[i].objectID == objectCharacterSheet.objectID){
                    //findCharacterSheet = data.Sheets[i];
                    objectCharacterSheet.characterName = data.Sheets[i].characterName;//findCharacterSheet.characterName;
                }
            }

        }
    }
}

[System.Serializable]
public class CharacterData{
    public List<CharacterSheet> Sheets;

}

Bump