- Home /
How can I Pool array of objects?
Hey Guys! I've made a game. It is having some performance issues in some mobile devices. It is an endless runner game where a lot of things get instantiated and destroyed. So I thought I should do something. I found the object pooling tutorial on unity live training archive. Maybe this can solve my problem.
I understood the logic but I need a bit of help with execution. Hope you guys can help.
I have 3 lanes. All the lanes have the Spawn Script attached to them, where it randomly generates an obstacle from the array of obstacles.
public class SpawnScript : MonoBehaviour {
public GameObject[] obstacles;
public float spawnMin = 1f;
public float spawnMax = 2f;
// Use this for initialization
void Start ()
{
Spawn ();
}
void Spawn ()
{
Instantiate (obstacles[Random.Range(0, obstacles.GetLength(0))], transform.position, Quaternion.identity);
Invoke ("Spawn", Random.Range(spawnMin, spawnMax));
}
I've tried using the procedure in Object Pooling Tutorial. The generic class with a public method to activate or get objects. But its generating all the obstacles in a single lane stacked over one another. I just want to know how can I instantiate or pool an array of different objects. Or how can I mimic the behaviour of the above script. I thought you guys can help me out.
If you can provide some code, it will be very helpful.
Please Help. Thank You.
Answer by Nick4 · Jul 15, 2014 at 11:32 PM
3 instances of spawnscript is running since you attached this to all 3 objects. So all 3 spawnscript instances are forced to pick one of the lanes and spawn them right where the instances' game objects are. That's why all lanes get instantiated in one place. Did you even wrote the game? If you did just store the lanes in an array. Disable them instead of destroying them and enable instead of Instantiating. I cannot write an example code because I'm on mobile but I will look into it when I get home tomorrow if the question is still available
@Nick4 You got me wrong I think. I'm not trying to instantiate lanes. Its the obstacles that I'm trying to instantiate here.
Suppose I have three obstacles in my obstacles array namely cube, sphere and capsule.
What I want to achieve here is to keep spawning one of these obstacles every 2 sec (or the time defined time between the range spawn$$anonymous$$in and spawn$$anonymous$$ax). I want to achieve this using object Pool.
Hope you got my question this time. I'm bit new as far as coding is concerned, so I need help from you guys.
Sorry! if I failed to explain my question better, Earlier.
Thank You.
Answer by Kiwasi · Jul 16, 2014 at 12:52 AM
I see nothing in your script that would do any pooling. In general a pool script looks like this
Your pool class instantiate enough objects to fill your pool. Every object is disabled. Every object is added to a list (or some other data structure).
Your spawn scripts will call on the pool class every time they need an object. The pool class grabs the next one off the list, enables it and places it in the scene. At the same time the object is moved off the list so it won't be used again
When the object is disabled it goes back to the pool class and gets added to the List again.
Here is a really crude coding example. It doesn't check that there are enough objects, or resize itself as more objects are needed. You can also expand it out to handle multiple types of GameObjects. Or you could simply create one pool for each obstacle.
public class Pool {
private List <GameObject> objects;
// Call this constructor to create the pool
public Pool (GamObject prefab, int size) {
objects = new List <GameObject>;
for (int i = 0; i < size, i++){
object = instantiate (prefab);
objects.Add(object);
object.SetActive(false);
}
}
// Call this method instead of Instantiate
public GameObject GetObject (Vector3 position, Quaterion rotation){
objects[0].transform.position = position;
objects[0].transform.rotation = rotation;
objects[0].SetActive(true);
objects.RemoveAt(0);
}
// Call this method instead of Destroy
public void ReturnObject (GameObject object){
object.SetActive(false);
objects.Add(object);
}
}
Edit: Removed the generic type. There is no particular need for this class to be generic.
@Bored$$anonymous$$ormon I know my script is not pooling, but that's what my question is. I've spawned different obstacles using that script and I'm asking how can I mimic the same thing using a pool. Sorry If I failed to explain my question better.
Answer by Shark-Boy · Aug 10, 2014 at 10:13 PM
What you need is a script that uses the GetPooledObject() method in the unity example (here is a link to a question that I asked and and later answered it has the ObjectPoolScript that I am using here) and set the object to one of three positions it would however have to pick one of three object pool scripts. To do this make an "ObstacleCreator" GameObject in your scene. Then create three child objects in the ObstacleCreator call them "SphereCreator", "CubeCreator" and "CapsuleCreator". Add a ObjectPoolScript to each of the child objects and fill in the space for the prefab with a Sphere GameObject and so on. Then add this script to the ObstacleCreator.
using UnityEngine;
using System.Collections;
public class TripleObjectPoolHandlerScript : MonoBehaviour
{
ObjectPoolScript[] objectPools;
/// <summary>
/// The positions. these are the positons of your spawn points
/// </summary>
public GameObject[] positions;
public float spawnTime = 3;
float timeSinceLastSpawn = 0;
// Use this for initialization
void Start ()
{
objectPools = GetComponentsInChildren<ObjectPoolScript> ();
}
// Update is called once per frame
void Update ()
{
timeSinceLastSpawn += Time.deltaTime;
if (timeSinceLastSpawn > spawnTime && objectPools != null)
{
timeSinceLastSpawn = 0;
CreateObstacle();
}
}
public void CreateObstacle()
{
int randomPool = Random.Range(0, objectPools.Length);
int randomPosition = Random.Range(0, positions.Length);
try
{
GameObject obj = objectPools[randomPool].GetPooledObject();
if(obj == null) return;
obj.transform.position = positions[randomPosition].transform.position;
obj.SetActive(true);
}
catch
{}
}
}
I did not try this script but the logic is all there. Also as you might have seen you should have three GameObjects in your scene for where you want the objects to spawn. Just drag them from the Hierarchy into the array in the Inspector.
Hope this helps.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Collider for road track in Unity3d car tutorial 0 Answers
Hide the ImageTraget in Real world 0 Answers
Shorten code with FOR loop 1 Answer