Projectile Object Pooling in RTS

Object Pooling seems really cool, and I relly wanted to implement it in my RTS game.
On the board: PROJECTILES
I didn’t want every unit to has it’s own pool. So I’ve implemented infamous singleton pattern for projectiles pooling, attached it to my Persistant Object Spawner.

Code for launching.

    public void LaunchProjectile(Transform projectileTransform, GameObject target, float damage)
    {
        ProjectileObjectPooler.instance.LaunchProjectile(projectile, projectileTransform, target, damage);
    }

Here is ProjectileObjectPooler class:

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

public class ProjectileObjectPooler : MonoBehaviour
{
    public static ProjectileObjectPooler instance = null;
    private Projectile currentProjectile = null;
    private Dictionary<GameObject, IObjectPool<Projectile>> dicPool = new();
    IObjectPool<Projectile> currentPool;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != this)
        {
            Destroy(gameObject);
            return;
        }   
    }

    public void LaunchProjectile(Projectile projectile, Transform projectileTransform, GameObject target, float damage)
    {
        currentProjectile = projectile;
        currentPool = GetCurrentProjectilePool(projectile.prefab);
        Projectile pooledProjectile = currentPool.Get();
        pooledProjectile.GetComponent<Projectile>().SetTargetAndPosition(target, damage, projectileTransform.position);
    }

    private IObjectPool<Projectile> GetCurrentProjectilePool(GameObject prefab)
    {
        if (!dicPool.ContainsKey(prefab))
        {
            dicPool[prefab] = new ObjectPool<Projectile>(
                CreateProjectile,
                OnGetProjectile,
                OnReleaseProjectile,
                OnDestroyProjectile);
        }
        return dicPool[prefab];
    }

    private Projectile CreateProjectile()
    {
        return Instantiate(currentProjectile.prefab).GetComponent<Projectile>();
    }

    private void OnGetProjectile(Projectile projectile)
    {
        projectile.gameObject.SetActive(true);
        projectile.transform.parent = null;
        IObjectPool<Projectile> poolCache = currentPool;
        projectile.OnProjectileFinished = ()=>
        {
            poolCache.Release(projectile);
        };
    }

    private void OnReleaseProjectile(Projectile projectile)
    {
        projectile.transform.parent = transform;
        projectile.gameObject.SetActive(false);
    }

    private void OnDestroyProjectile(Projectile projectile)
    {
        Destroy(gameObject);
    }
}

My biggest hurdle in this was that Unity’s Object Pool class doesn’t really care about what type of GameObjects are in the pool. So for e.g. if I would’ve put fireball and arrow projectiles to the same pool - archers occiassionaly would’ve fire fireballs instead of arrows.

My Projectile class has it’s GameObject prefab field. I needed to create Object Pool for each prefab type. What I had to do was to use Dictionary<GameObject, IObjectPool>

It’s working well.

That’s an excellent approach! Well done!

I promise not to tell Sam. :stuck_out_tongue:

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.

Privacy & Terms