Populating custom class items (containing a list) from another script

Hi. I have been learning how to use custom classes and using them to store information about monsters in a card game I’m working on. First I should say that I can make this work by directly inputing all the information into the inspector, but I want to determine where I’m going wrong with my scripts where I try to populate information. The problem I believe is with the list object. Heres the custom class code. [System.Serializable] is present for the public class.

public class Monster
{
    public string name;
    public int id;
    public string description;
    public List<int> attackpattern;

    public Monster()
    {
    // This is my "empty constructor"
    }
  
// For the main constructor I wasn't sure how to define the list item
    public Monster(string name, int id, string description)
    {
        this.name = name;
        this.id = id;
        this.description = description;       
    }
}  

I then tried to populate these items through a second script (attached to empty game object), as follows:

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

public class Monsters : MonoBehaviour
{
    // I tried doing this two ways, first by defining two specific monsters..
    public Monster Monster1;
    public Monster Monster2;
   // .. and then by creating an array of monsters
    public Monster[] monsters;

    void Start()
    {
        // I added the following line during testing, but initially set the value in the inspector
        monsters = new Monster[10];
       
        Monster1 = new Monster("Alpha", 1, "Wolf");
        Monster2 = new Monster("Beta", 2, "Slime");
        
       // The following lines worked IF I defined Monster1 in the inspector, but return object reference not set to instance error if I populated through code
        Monster1.attackpattern.Add(2);
        Monster1.attackpattern.Add(4);
       
        monsters[0] = new Monster("Alpha", 1, "Alpha monster");

// The following commands work IF I remove the array size command and define monsters[0] in the inspector but not through the line above.
        monsters[0].attackpattern.Add(2);
        monsters[0].attackpattern.Add(4);
        int randomX = Random.Range(1, 5);
        monsters[0].attackpattern.Add(randomX);
        Debug.Log(monsters[0].attackpattern.Count);
        for (var i = 0; i < monsters[0].attackpattern.Count; i++)
        {
            Debug.Log(monsters[0].attackpattern*);*

}
}
}
I’m not entirely sure where I’m going wrong. I am using the list item because each monster will have a different attack list which may be different lengths. I’ve read many articles about custom classes and as I said I wonder if I need to ammend the public class to somehow include the list item in the constructor, but if so I cannot figure out what the code will be there and then what I’d need to add in the second script. To state again, I can make this work nicely by editing everything into the inspector, but I’d like to know how to do it through a script if thats possible. I hope this made sense and I appreciate any help you can give.

Try this its much more cleaner and more extendable.

The root of your problem is that you forgot to initialize the list itself.

public Monster()
{
   attackpattern = new List<int>();
}

public Monster(string name, int id, string description)
{
   this.name = name;
   this.id = id;
   this.description = description;
   attackpattern = new List<int>();
}

public Monster(string name, int id, string description, List<int> attackpattern)
{
   this.name = name;
   this.id = id;
   this.description = description;
   this.attackpattern = attackpattern;
}

I have corrected your constructor methods. You can even construct a Monster object with a pre-existing list.

Monster monster = new Monster("name", 1, "desc", new List<int>() {2, 3, 5});