Constructors and AddComponent for generic object pool

Hello. I have a functioning object pool code in my gamemanager class which works fine, but I’d like to make it more abstract and move it out of the gamemanager so that it could be reused later. I’m also hoping this could help me write cleaner code. However, I’m apparently misunderstanding something about how classes should be instantiated in Unity.

My manager class looks like this:

using System.Collections.Generic;
using UnityEngine;

public class MainTest : MonoBehaviour {

	public GameObject prefab;

	void Start () {
		ObjectPool pool = new ObjectPool (prefab, 5, "Prefab");
		pool.Pool ();
	}
}

The above is attached to an empty GameObject so that it starts when the game starts. The ObjectPool script isn’t attached to anything and looks like this (I’m not adding any more functionality until I figure this out):

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

public class ObjectPool : MonoBehaviour {

	private List<GameObject> objectPool;	

	public ObjectPool(GameObject obj, int count, string name)
	{
		objectPool = new List<GameObject>();
		GameObject root = new GameObject ();
		root.name = String.Format("{0} Object Pool", name);
		for (int i = 0; i < count; i++)
		{
			GameObject go = Instantiate (obj, Vector3.zero, Quaternion.identity);
			go.name = name + " " + i;
			go.transform.parent = root.transform;
			go.SetActive (false);
			objectPool.Add (go);
		}
	}

	public GameObject Pool()
	{
		foreach (GameObject obj in objectPool)
		{
			if (!obj.activeSelf)
			{
				obj.SetActive (true);
				return obj;
			}
		}
		Debug.Log ("Pool is at maximum");
		return null;
	}
}

This works as expected for now, but I’m getting this warning in the Unity console: “You are trying to create a MonoBehaviour using the ‘new’ keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all”.

I’m all for not inheriting from MonoBehaviour but I need it in order to use Instantiate.

Does the warning mean that in order to create an object pool I need to add an ObjectPool component to my empty GameObject (the one containing the gamemanager class) instead of using “new”? Or am I approaching this problem incorrectly?

Thanks.

Why did you inherit from mono behaviour if you will not use nothing that monobehaviour will provide you as: Update, Start, Awake, OnCollisionEnter and all those methods and properties?

Rule n#1 if you don’t need what a told you above, don’t inherit from it.
Just create a class instance like every day. (new MyClass())
Remove the MonoBehaviour inheritance, and in your method called Instantiate:

  UnityEngine.Object.Instantiate(/*Required paramenters etc..*/);

And that’s it.

But if you want to call a MonoBehaviour child class that you don’t have in your current object
In the caller class, just use GetComponent<>(); and find the object that contains the class that you like.

  var myClassInstance = 
  GameObject.Find("MyObjectWithTheClassMyClass").GetComponent<MyClass>();

  myClassInstance .APropertyExample = "Hey";

If your script is in the same object:

 var instanceClass = GetComponent<MyClass>();

Example:
Class2

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

public class ObjectPool
{

   private List<GameObject> objectPool;    

 public ObjectPool(GameObject obj, int count, string name)
 {
     objectPool = new List<GameObject>();
     GameObject root = new GameObject ();
     root.name = String.Format("{0} Object Pool", name);
     for (int i = 0; i < count; i++)
     {
         GameObject go = UnityEngine.Object.Instantiate(obj, Vector3.zero, Quaternion.identity);

         go.name = name + " " + i;
         go.transform.parent = root.transform;
         go.SetActive (false);
         objectPool.Add (go);
     }
 }

 public GameObject Pool()
 {
     foreach (GameObject obj in objectPool)
     {
         if (!obj.activeSelf)
         {
             obj.SetActive (true);
             return obj;
         }
     }
     Debug.Log ("Pool is at maximum");
     return null;
 }
}

And you can create an instance with the new keyword.

var objectPool = new ObjectPool(myGameObject, 1234, "MyString");

But if your objectPool class was like this:

 public class ObjectPool : Monobehaviour
 {
         Public void GetValues(GameObject obj, int count, string name)
         {
                 //The same work
         }

         public GameObject Pool()
         {
               //The same Work
         }
 }

You would need to call it in this way:

   var pool = GameObject.Find("MyObjectWithMyClass").GetComponent<MyClass>();

But if the class is in your current object:

  var pool = GetComponent<MyClass>();