How to create object pool of random range size?

Hi everyone, I’m new to scripting so please excuse me if this question is insultingly basic.

Following a tutorial on youtube I’m creating a dictionary of pools that should eventually spawn terrain tiles for my world (I want to make the terrain generate randomly each time the scene is run) but unlike in the tutorial, in which they use a fixed size of Pool (defined by “public int size;” within the “public class Pool”) I want to make the Pool size partially random using Random.Range. Unfortunately Visual Studio reports an error CS0120. How do I make it work?

Thank you in advance for any suggestions.

The first error you see is clear about what is going wrong: An object reference is required for the non static field, method or property. It means you need an instance of the object before you can assign values to it.

To solve your issue you should assign a value to your ‘size’ field after you have created an instance of ‘Pool’, because now you are trying to set it with values that do not exist.

Also, posting code in code tags instead of posting a screenshot is much easier for people trying to help you :wink:

Anyhew, if anything is unclear of how you should solve your issue, I’ll be happy to explain more in-depth.

1 Like

Thank you for your explanation, however I actually could use a little more depth.

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

public class TerrainPooler : MonoBehaviour
{
    [System.Serializable]
    public class Pool
    {
        public string tag;
        public GameObject prefab;
        public int minsize;
        public int maxsize;
    }

    public int size = Random.Range(Pool.minsize * 1f, Pool.maxsize * 1f);

    public List<Pool> pools;
   
    public Dictionary<string, Queue<GameObject>> poolDictionary;

    // Start is called before the first frame update
    void Awake()
    {
        poolDictionary = new Dictionary<string, Queue<GameObject>>();


        foreach (Pool pool in pools)
        {
            Queue<GameObject> objectPool = new Queue<GameObject>();

            for (int i = 0; i < size; i++)
            {
                GameObject obj = Instantiate(pool.prefab);
                obj.SetActive(false);
                objectPool.Enqueue(obj);
            }
           poolDictionary.Add(pool.tag, objectPool);
        }
    }
}

Thank you for the code tag tip too, when writing my question I didn’t know that was an option.

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

public class TerrainPooler : MonoBehaviour
{
    [System.Serializable]
    public class Pool
    {
        public string tag;
        public GameObject prefab;
        public int minsize;
        public int maxsize;
    }

    public int size;

    public List<Pool> pools;

    public Dictionary<string, Queue<GameObject>> poolDictionary;

    // Start is called before the first frame update
    void Awake()
    {
        poolDictionary = new Dictionary<string, Queue<GameObject>>();


        foreach (Pool pool in pools)
        {
            size = Random.Range(pool.minsize, pool.maxsize);

            Queue<GameObject> objectPool = new Queue<GameObject>();

            for (int i = 0; i < size; i++)
            {
                GameObject obj = Instantiate(pool.prefab);
                obj.SetActive(false);
                objectPool.Enqueue(obj);
            }
            poolDictionary.Add(pool.tag, objectPool);
        }
    }
}

That should do the trick :slight_smile:
You need an instance of your Pool class (like your “pool” variable in your foreach loop) before you can use it. You were attempting to use values from the Pool class directly, while you should first create a Pool class reference to be able to assign values or read from its fields.

1 Like

Oh I see, thank you very much! I wasn’t able to comprehend the principle before seeing it done the right way, now when I do, it actually seems perfectly logical.

Glad I could help you out :slight_smile:
I have a question tho…
If you define your Pool class inside your TerrainPooler class, then how do you fill the public field “pools” in the editor?
Shouldn’t the Pool class be a separate script attached to GameObjects that you then drag onto the public “pools” field?

Well in this aspect I followed the tutorial. Basically back in the Inspector in Unity - under TerrainPooler script attached to empty object it creates the Pooler class which itself can’t be filled but can be opened (there is the little arrow) and once you open it, it shows “Size” field in which you define how many different object types / pools you want. Then you drag individual objects inside “prefab” field which is created for each abovementioned element/object type/pool. I’m not sure if this answered your question, neither am I sure whether this should or shouldn’t work but fortunately it does, that I know from test.

Perhaps if you were referring to the actual spawning of individual object clones from these pools that indeed requires another script for each object type which is attached to the original object.

In case you are interested in a description of higher quality than mine, this is the tutorial I followed (except for the not included random pool size part, which you kindly solved for me)

Ok thanks now I understand (love the tutorials from that guy btw :slight_smile: )

1 Like

You are very welcome. Me too, he is really great :slight_smile: