If you want to use a separate manager for each type of prefab, you can make PoolManager an abstract generic class and then add concrete implementations. Here's an abbreviated example; for brevity, I won't rewrite the entire class (// [...] indicates where code has been omitted):
public class PoolManager<T> : MonoBehaviour where T : Component
{
[SerializeField] private T _prefab;
[SerializeField] private int _poolAmount;
[SerializeField] private bool _usePool = true;
private ObjectPool<T> pool;
// [...]
private T CreateInstance()
{
T instance = Instantiate(_prefab);
instance .transform.SetParent(_poolContainer.transform);
instance.gameObject.SetActive(false);
return instance ;
}
// [...]
}
public class ProjectilePoolManager : PoolManager<Projectile> {
// This concrete implementation doesn't need any additional code!
}
public class EnemyPoolManager : PoolManager<Enemy> {
// This concrete implementation doesn't need any additional code!
}
This is the approach I typically use.
If you want one pool manager component to manage all of your pools, rather than having a separate pool manager for each type of pool, that gets more complicated. I don't have time at the moment to write a full example for that.