Currently I have created a generic object pool using the live tutorial video, however unlike the tutorial I want to use object pools for multiple randomly generated objects which are being randomly generated on an array of transfroms. This is the original script i was using before i started learning about object pools.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generation : MonoBehaviour {
// These are the spawn point arrays that are being used as placement for what's being spawned
public Transform[] terrainPoints;
public Transform[] obstaclePoints;
public Transform[] middlePoints;
// These are the actual list of prefabs that will be spawning
public GameObject[] terrainSpawn;
public GameObject[] obstacleSpawn;
public GameObject[] middleSpawn;
// These are the time intervals in which the spawnings will occur
public float terrainTimer = 2;
public float obstacleTimer = 2;
public float middleTimer = 2;
public float newTime = 2;
// This is the bool that determines whether the game will be pause (this is accessed by another script, not set by this one)
public bool isPause;
// This is accessing the level ring of the level, this isn't set in the inspector this is set dynamically
public GameObject theGround;
public static Generation S;
void Awake()
{
S = this;
theGround = GameObject.Find("level ring");
}
// Update is called once per frame
void Update () {
// If isPause is set to false then we proceed to spawn the clones using the custom functions
if(isPause == false)
{
TerrainSpawn();
ObstacleSpawn();
MiddleSpawn();
}
}
// This is the function thats being called thats doing the spawning for terrain prefabs
void TerrainSpawn()
{
// This is taking the duration of time and decreasing it by a set frame
terrainTimer -= Time.deltaTime;
// If this is below or equal to zero, it spawns a new clone
if(terrainTimer <= 0)
{
// This randomly chooses an indexed prefab and transform and spawns something at those points
GameObject terrainClone = Instantiate(terrainSpawn[Random.Range(0, terrainSpawn.Length)], terrainPoints[Random.Range(0, terrainPoints.Length)].transform.position, transform.rotation);
terrainClone.transform.parent = theGround.transform;
// This resets the duration of time for the next spawn
terrainTimer = newTime;
}
}
// This is the function called to spawn the obstacle clones
void ObstacleSpawn()
{
obstacleTimer -= Time.deltaTime;
if(obstacleTimer <= 0)
{
GameObject obstacleClone = Instantiate(obstacleSpawn[Random.Range(0, obstacleSpawn.Length)], obstaclePoints[Random.Range(0, obstaclePoints.Length)].transform.position, transform.rotation);
obstacleClone.transform.parent = theGround.transform;
obstacleTimer = newTime;
}
}
// This is the function being called to spawn clones for the middle section prefabs
void MiddleSpawn()
{
middleTimer -= Time.deltaTime;
if(middleTimer <= 0)
{
GameObject middleClone = Instantiate(middleSpawn[Random.Range(0, middleSpawn.Length)], middlePoints[Random.Range(0, middlePoints.Length)].transform.position, transform.rotation);
middleClone.transform.parent = theGround.transform;
middleTimer = newTime;
}
}
}
originally i had several transforms for each tier of obstacles and or terrain prefabs in turn would be randomly generated on. However object pooling is def. needed here because this is meant for mobile. Does anyone have any ideas on how i could keep the same format/functions but gear this more towards object pooling?
Again i have searched online for possible solutions along with the tutorials on here for object pooling but most of it is geared towards one object and or spawning them normally.
What You can do is make growing object pool. Basically system spawns new object only when it is needed and place it into pool. Then You can have like separate pool for each type of object. Then all You have to do is to Random.Range pick type of element and have if statements that will pool and move pooled object. At least I would do it like so.
1 Like
Thank you for the response, Yeah I’ve seen that type of method with the growing object pool. My question is, would all of the objects be put into the one object pool list? Also making a separate pool for each object, would that still work with the current script idea i had?
If it matters what type of object you get (including wanting the random objects to be evenly distributed), then put each type in a separate pool. If it doesn’t, you can put everything in one pool.
Putting it in one pool means you might get a run of the same type of object - for instance, if the player just destroyed a bunch of mailboxes, then the pool will have a bunch of mailboxes in it and the next several objects requested will all be that one.
1 Like
ahhh I see. Yeah currently everything is being spawned on a level ring that is constantly spinning, one set of spawners is used for terrain objects and the others are the obstacle spawns. But with in each of the spawns, its randomly picking a set of prefabs to spawn. So making separate pools is most likely needed?
Hm well You could use dictionary instead of list to store Your objects. Use string for the key and GameObject for value. Only problem is that dictionaries must have unique keys (same as lists) so what You would have to do is sorting keys with numbers. So for example You have a Box prefab so You put first object with key “Box_0”, next box that will be instantiated and added to pool will have key “Box_1” and so on. If You have um laser You could store it same way in the same dictionary and all of them would not get mixed. Then with random.range You would select what to spawn, create a string and use for loop to go through dictionary to check if there are any free objects. If not spawn new one and give it higher key.
I think that is best solution for what You are looking for.
1 Like
Thank you both for the replies, Bantaru i will check into trying something like that, it sounds slightly difficult but ill give it a whirl! if anyone else has any other ideas, I’m still open to more suggestions.
it was also suggested to me to maybe use a list of lists for the different objects? Here is the basic generic list. How could i make several different lists for objects? and if so how could i randomize them?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPoolerScript : MonoBehaviour {
public static ObjectPoolerScript current;
public GameObject pooledObject;
public int amountPooled = 20;
public bool willGrow = true;
List<GameObject> pooledObjects;
// Use this for initialization
void Start () {
pooledObjects = new List<GameObject>();
for(int i = 0; i < amountPooled; i++)
{
GameObject obj = (GameObject)Instantiate(pooledObject);
obj.SetActive(false);
pooledObjects.Add(obj);
}
}
public GameObject GetPooledObject()
{
for(int i = 0; i < pooledObjects.Count; i++)
{
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[i];
}
}
if (willGrow)
{
GameObject obj = (GameObject)Instantiate(pooledObject);
pooledObjects.Add(obj);
return obj;
}
return null;
}
// Update is called once per frame
void Update () {
}
}
FYI - you can delete posts, so go back and delete past “bumps” as not to clog up the thread with extra space…
Anyway…
When you say randomize them… I guess you mean have them be of a wide variety of types right?
If so, figure out exactly what every single possible type you intent to use is, and once you know that, create some type of set of builder methods that takes many different parameters, depending on the type handed to it, and assigns it into its own pool of other matching types. Like lets say you wanted to have pooling of bullets, and pooling of explosion graphics, and maybe pooling of enemies… you could create 3 separate methods like “CreateOrAddToPool(SomeType someType)…” that allow each type to be used in the same named method, then you handle them slightly differently to find the specific pool, add the object, and later disable/enable it to use during runtime.
Does this make sense? Is that sort of what your asking?
1 Like
No, the “bumps” will continue to stay, because i don’t appreciate being told what to do by a stranger. However i do appreciate your answer and the advice, so thank you. I understand what you are saying and will try it. Thanks again.
I didn’t mean to sound rude or anything, just thought maybe you hadn’t noticed that feature of the forum 
When I see posts that have many replies, I assume the problem has been solved in most cases…
1 Like
I understand completely. I just was trying to keep it updated and refreshed mainly because this is kinda a crippling crisis for the mobile game im trying to put out, but object pooling has had me confused all day lol i mean i get the concept and i get the basic format for a single object however randomizing between prefab spawns between random transforms makes the object pooling really confusing for me. Thank you for taking the time to post, maybe ill get this going before dead line lol
Object pooling is really a simple concept, but can be tricky to wrap your mind around in actual use.
I think the best way to really think about the concept of object pooling is to break down what there is going to be in your game that is dynamic or often recreated and removed, like a shooter game has lots of explosions, lots of “bad guys” and things that get instantiated/spawned and then later destroyed/despawned. A game like GTA has cars, pedestrians, street lamps, benches… things that interact physically or move around (not static world stuff) and often get “destroyed” when they are distant or out of view from the player, or things that rapidly get instantiated like missiles from a helicopter… these are the important things to pool because you don’t want to instantiate and destroy a lot of them, or you clog up the processor and memory trying to create tons of new ones and collect the garbage of old unused/destroyed things… these are good cases where having a pool pre-loaded and ready to “move and activate” rather than instantiate, is the best way to approach it.
Disabling/enabling gameobjects and components is faster than creating and destroying them, so thats the basic idea behind it all, is to avoid Instantiate and Destroy… but when your spawning players, or uhhh… buildings that are unique… you know, anything that only gets created or destroyed if you come within range of it or not very often, these types of things don’t really need pooled, because they are kind of special to the area/use in the game.
Really not that many things in games need pooling in a lot of cases, but just a few sets of things with specific rapidly used kinds things.
The actual code to do that is usually very specific to the game, and you could hardcode a specific number in an array (like for instance, 100 bullets per player, assuming the player can’t fire more than that ever fast enough to exceed that number) and just reuse them over and over, or you could use a generic list or dictionary as a dynamic growing pool, and create new ones on the fly to expand the pool to have however many get created at runtime, and both approaches have advantages and disadvantages. Doing a hardcoded number of them, means you might accidentally make a way to exceed the limit and cause an error, or you might have more than you ever really need at a time, and waste memory on them. But making them dynamic will cause hiccups if lots of them are instantiated fresh at the beginning of the game (a player or two start shooting like crazy and making lots of bullets or lots of explosions) or similar issues.
Hope that helps 
1 Like
That makes a lot more sense! Thank you for going to greater detail on the subject, i tried making a script like this which in theory seemed to be a good idea however its not cycling through the stuff being spawned.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPoolerScript : MonoBehaviour {
[SerializeField]
private GameObject[] objectPrefabs;
private List<GameObject> pooledObject = new List<GameObject>();
public static ObjectPoolerScript S;
void Start()
{
S = this;
}
public GameObject GetObject(string type)
{
foreach(GameObject go in pooledObject)
{
if(go.name == type && !go.activeInHierarchy)
{
go.SetActive(true);
return go;
}
}
for(int i = 0; i < objectPrefabs.Length; i++)
{
if(objectPrefabs[i].name == type)
{
GameObject newObject = Instantiate(objectPrefabs[i]);
pooledObject.Add(newObject);
newObject.name = type;
return newObject;
}
}
return null;
}
public void ReleaseObject(GameObject gameObject)
{
gameObject.SetActive(false);
}
}
and here is the code deactivating the spawned objects
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyClones : MonoBehaviour {
void OnEnable()
{
Invoke("Release", 7);
}
void OnDisable()
{
CancelInvoke();
}
private void Release()
{
ObjectPoolerScript.S.ReleaseObject(gameObject);
}
}
Do i maybe need to change something in the generation script?