How can I create and pull from a pool of reusable objects (like bullets, enemies, explosions, etc) rather than Instantiating and destroying them during gameplay?
I've seen several forum responses mention that you should create a pool of objects at Start and pull from them when needed however, I've never seen any complete script and/or scene setup examples of how to do it.
It depends on how much you know about your game. The more you know the more optimizations you can make.
Lets assume you need bullets, and in your game you know there will never be more than 1000 bullets on screen at once.
This is the start of a class which will get you the next bullet in the array when asked.
public class BulletGetter : MonoBehaviour {
GameObject[] bullets;
int lastBullet = -1;
int bulletCache = 1000;
void Awake(){
bullets = new GameObject[bulletCache];
for(int i=0; i<bullets.Length; i++){
bullets *= new GameObject ("Bullet-"+i);*
*}*
*}*
*int GetNextBullet(){*
*lastBullet +=1;*
*if(lastBullet > bulletCache-1){*
*lastBullet = 0;//reset the loop*
*}*
*return lastBullet;*
*}*
*}*
*```*
*<p>Various improvements could be made to this, such as activating and deactivating bullets as they are in use, automatically increasing the array size if you for some reason end up with more than 1000 bullets on screen, etc. Also, instead of creating gameObjects, you could instantiate prefabs in awake.</p>*
*<p>The most important part of doing a caching system is making sure all your cached objects have a method which will return them to their original unused state. Since you no longer will simply destroy and create a new object, its helpful to code your scripts in such a way that you can easily track and revert the state of the object.</p>*
Here's a javascript pool class I developed for Intergalactic Sheep Pong. It allows you to pre-instantiate a specific number of prefab instances. It will also dynamically grow if you end up needed more objects than you originally allocated.
A simple array is more efficient if you know the maximum number of objects you need to instantiate, but the .NET collections are pretty fast, too, and support dynamic resizing.
I hope this is helpful. If anyone has any suggestions on how this code could be improved, feel free to comment.
I had a different answer here before which was pretty convoluted and probably not very helpful. Here’s a revised script which is similar to Brain’s but more complete.
Here’s the main code for handling the object pool (bullets in this case):
public class BulletPool : MonoBehaviour {
public Bullet[] bullet;
private int bulletCache = 0;
private int activeBullet = 0;
void Start () {
bulletCache = (bullet.Length);
}
void FireBullet() {
bullet[activeBullet].Fire(); // fire the bullet
activeBullet+=1;
if(activeBullet > bulletCache-1){
activeBullet = 0;//reset the loop
}
}
}
This script is called every time a bullet is fired, add code to this script to handle bullet movement and other behaviors:
public class Bullet : MonoBehaviour {
void Fire() {
// code that makes your bullet move
}
}
I'm using it on iPhone as well but this package is an older version that uses some generics that aren't supported yet on Unity iPhone 2.6 - It should work as is in the upcoming Unity 3 though.
int bulltNo;
public GameObject[] objBullt;
public AudioSource shoot;
public FrisBullet[] bullt;
int a;
float Cooler;
//bool cooldown;
// Use this for initialization
void Start () {
//Declare an array of an invariable number
bulltNo = GameObject.FindGameObjectsWithTag ("Bullet").Length;
objBullt = new GameObject[bulltNo];
bullt = new FrisBullet[bulltNo];
objBullt = GameObject.FindGameObjectsWithTag ("Bullet");
//specific amount of loops
for(int i = 0;i<bulltNo;i++){
bullt _= objBullt*.GetComponent<FrisBullet>();*_
* }* * a = 0;* }
* // Update is called once per frame* * void Update () {* _ transform.Rotate (new Vector3 (0, 50 * Input.GetAxis (“Horizontal”) * Time.deltaTime, 0));_ * if(Input.GetMouseButton(0))* * {* * bullt[a].StartCoroutine(“Fritter”);* * a++;* * if(a >= bulltNo) a = 0;*
* }* * if (Input.GetMouseButtonUp (0))* * shoot.Stop ();* * if (Input.GetMouseButtonDown (0))* * shoot.Play ();*
* }* } ------------------------------------------------------- Attatch the above script to you Character or weapon Attatch the below script to your bullet ------------------------------------------------------- using UnityEngine; using System.Collections; public class FrisBullet : MonoBehaviour { * public float time;*
* Transform firelocke;* * // Use this for initialization* * void Start () {* * firelocke = GameObject.FindGameObjectWithTag (“Nuzz”).GetComponent ();* * }*
* // Update is called once per frame* * void Update () {*