Object Pooling without using GetComponent.

Hello everyone, so I’m trying to create a Object Pooling script that does not use GetComponent.

Here are the reasons why I use GetComponent:

The Script

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

// Set object to parent this organizer on hierarchy
[SerializeField]
 private Transform pooledObjectsTransform = null;

// Objects
[System.Serializable]
public class Pool
 {
   public string tag;
   [AssetsOnly]
   public GameObject prefab;
   public int size;
}

[SerializeField]
private List<Pool> pools = null;       

        /// <summary>
        /// Spawn Prefab with Tag at new Position and new Rotation.
        /// </summary>
        /// <param name="Tag"></param>
        /// <param name="Position"></param>
        /// <param name="Rotation"></param>
        /// <returns></returns>
public GameObject SpawnFromPool(string Tag, Vector3 Position, Quaternion Rotation)
{
      if (!poolDictionary.ContainsKey(Tag))
      {
        Debug.LogWarning("Pool with name" + Tag + " doesn't exist.");
        return null;
      }

      GameObject objectToSpawn = poolDictionary[Tag].Dequeue();

      objectToSpawn.SetActive(true);
      objectToSpawn.transform.position = Position;
      objectToSpawn.transform.rotation = Rotation;

      // Call object on spawn method
       IPooledObjects[] _pooledObj = objectToSpawn.GetComponents<IPooledObjects>();

       if (_pooledObj != null)
       {
            foreach (IPooledObjects pooledObj in _pooledObj)
            {
               pooledObj.OnObjectSpawn();
            }
       }

       poolDictionary[Tag].Enqueue(objectToSpawn);

       return objectToSpawn;
}

So everytime I spawn an object it will call a GetComponent to get the interface IPooledObjects and in some cases everytime I pool an object I’ll try to get a script from it to modify some values, the idea is to store this core scripts somewhere so I only call the GetComponent once, not everytime I spawn the object.
I thought of Generic Types, something around creating a class that can store any script as a type, but I still can’t wrap my head around it.

Thanks for your time!

While yours is probably a workable pool solution, you may want to look into the following improvements that will allow you to eschew the GetComponen() calls:

The overriding proncible with pooled objects is that they are regarded as in the pool when inactive. If you can make that happen, you can apply the following changes

  • Do not deque objects when you spawn them, leave them in the pool. Simply activating them will ‘remove them’ from the pool. Looking for a pooled object means that you’ll have to check against ‘isActive’
  • Returning the object to the pool is instantaneous by setting it inactive.
  • Since setting a pooled object active means Setting it active, you can use OnEnable() to invoke OnObjectSpawned on all components - GetComponent is no longer required

Refinements would be to replace the List with a Dictionary,

1 Like

Thanks for the tip! Going tTo make this changes asap.

But what about using the GetComponent to acess the script after they are spawned? For example:

ProjectileScript projectile = ObjectPooler.instance.SpawnFromPool("Prefab", tranform.position, transform.rotation).GetComponent(ProjectileScript);

projectile.damage = etc;
projectile.speed = etc;

I would like to know if there is anyway to get this component without using the GetComponent. Like storing the script (ProjectileScript) in some generic variable, or something like that, so the GetComponent is called only once not everytime the object is spawned.

I’m creating a shooter game and a lot of projectiles are spawned all the time and I know i’m not doing the most performant coding.
Thanks.

1 Like