Custom class with coroutine can't be added using the "new" keyword

As the title suggests, the error is obvious but the workaround is not. I have an RTS-style game where, in the gameworld, there are resource nodes. The resource nodes have individual spawnpoints onto which the resources themselves can spawn. Whenever an NPC wishes to go and retrieve some of these resources, a reservation request is sent and stored in a “Reservation” object. This Reservation object is a custom class, which holds a reference to the NPC who made the reservation, as well as a list of the spawnpoints that were reserved.

HOWEVER, built into this Reservation object, I have a method for removing the first entry on the list of spawnpoints. Accessing this function is no problem, but I wanted to introduce a delay so that it does not happen immediately. For this I built an IEnumerator which simply waits for a specified delay before calling this entry removal function. For this IEnumerator to work, I had to inherit my Reservation class from MonoBehavior.

But this meant that I could no longer initialize my newly added reservations using the New keyword. Here’s the code I use to illustrate my problem. First there’s the class in question:

    public class Reservation : MonoBehaviour
    {
        //The Wisp who made the reservation
        public WispScript WispScriptRef;
        //A list of the resource node spawnpoints whose resources were reserved to this wisp
        public List<RNodeSpawnpoint> RNodeListSpawnpointList = new List<RNodeSpawnpoint>();

        //Used to indicate whether a Wisp is currently in transition between resource spawnpoints
        public bool ReservationExecuting = true;    //Initialized to true, as we know someone made the reservation

        //Add the passed Spawnpoint to the Reservation's list of spawnpoints
        public void MakeReservation(RNodeSpawnpoint SpawnpointToReserve)
        {
            RNodeListSpawnpointList.Add(SpawnpointToReserve);
        }

        //Remove the last element in the list
        public void RemoveLastReservation()
        {
            RNodeListSpawnpointList.RemoveAt(0);
        }
        //Call RemoveLastReservation at a delay
        public IEnumerator DelayedRemoveLastReservation(int DelayTime)
        {
            yield return new WaitForSeconds(DelayTime);
            RemoveLastReservation();
        }
        //Allow external scripts to call the IEnumerator above
        public void CallDelayedRemoveLastReservation(int DelayTime)
        {
            StartCoroutine(DelayedRemoveLastReservation(DelayTime));
        }
    }

Here’s the line I use to create a list to contain these objects:

    //Holds a reference to all of our reservation-objects
    public List<Reservation> ReservationList = new List<Reservation>();

And here’s the line I use to add items to that list, which is where I believe that the problem might be occurring:

        Reservation NewReservation = new Reservation();

Right after that line of code, I simply initialize the member variables inside the Reservation object before I then add it to the list of Reservation objects via:

ReservationList.Add(NewReservation);

Unity suggests I use AddComponent() instead, but how would I go about getting the same result then? All I want is to have a list of the Reservation objects.

I’m considering moving the IEnumerator out of the Reservation class and simply having the object making these calls, do the waiting instead. It would solve my problem, but it would decentralize my code in a way that is not optimal for my design standard and add unnecessary steps to the production chain later.

Thanks in advance!

  • Dave

Scripts inheriting from MonoBehaviours can’t be instantiated using the new keyword.

You have two possibilities :

  1. Remove the inheritance in the Reservation class. If a Reservation instance is not meant to be attached on a gameobject, it’s the way to go. However, you won’t be able to start a coroutine within this class (but you can leave the coroutine definition and run from an other MonoBehaviour)

  2. Use the following snippet :

    Reservation NewReservation = new GameObject(“Resevation”).AddComponent();