Skip to content

Instantly share code, notes, and snippets.

@zaun
Created February 22, 2016 17:43
Show Gist options
  • Save zaun/d560559b3366dd5e001b to your computer and use it in GitHub Desktop.
Save zaun/d560559b3366dd5e001b to your computer and use it in GitHub Desktop.
Unity3D Pools
using UnityEngine;
using System.Collections;
public class Effect : MonoBehaviour
{
/// <summary>
/// The array of emitters to fire when the effect starts.
/// </summary>
public ParticleEmitter[] emitters;
/// <summary>
/// The length of the effect in seconds. After which the effect will be reset and pooled if needed.
/// </summary>
public float effectLength = 1f;
/// <summary>
/// Should the effect be added to the effects pool after completion.
/// </summary>
public bool poolAfterComplete = true;
/// <summary>
/// Resets the effect.
/// </summary>
public virtual void ResetEffect ()
{
if(poolAfterComplete)
{
ObjectPool.instance.PoolObject(gameObject);
} else {
Destroy(gameObject);
}
}
/// <summary>
/// Starts the effect.
/// </summary>
public virtual void StartEffect ()
{
foreach ( ParticleEmitter emitter in emitters )
{
emitter.Emit();
}
StartCoroutine(WaitForCompletion());
}
public IEnumerator WaitForCompletion ()
{
//Wait for the effect to complete itself
yield return new WaitForSeconds(effectLength);
//Reset the now completed effect
ResetEffect();
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ObjectPool : MonoBehaviour
{
public static ObjectPool instance;
/// <summary>
/// The object prefabs which the pool can handle.
/// </summary>
public GameObject[] objectPrefabs;
/// <summary>
/// The pooled objects currently available.
/// </summary>
public List<GameObject>[] pooledObjects;
/// <summary>
/// The amount of objects of each type to buffer.
/// </summary>
public int[] amountToBuffer;
public int defaultBufferAmount = 3;
/// <summary>
/// The container object that we will keep unused pooled objects so we dont clog up the editor with objects.
/// </summary>
protected GameObject containerObject;
void Awake ()
{
instance = this;
}
// Use this for initialization
void Start ()
{
containerObject = new GameObject("ObjectPool");
//Loop through the object prefabs and make a new list for each one.
//We do this because the pool can only support prefabs set to it in the editor,
//so we can assume the lists of pooled objects are in the same order as object prefabs in the array
pooledObjects = new List<GameObject>[objectPrefabs.Length];
int i = 0;
foreach ( GameObject objectPrefab in objectPrefabs )
{
pooledObjects[i] = new List<GameObject>();
int bufferAmount;
if(i < amountToBuffer.Length) bufferAmount = amountToBuffer[i];
else
bufferAmount = defaultBufferAmount;
for ( int n=0; n<bufferAmount; n++)
{
GameObject newObj = Instantiate(objectPrefab) as GameObject;
newObj.name = objectPrefab.name;
PoolObject(newObj);
}
i++;
}
}
/// <summary>
/// Gets a new object for the name type provided. If no object type exists or if onlypooled is true and there is no objects of that type in the pool
/// then null will be returned.
/// </summary>
/// <returns>
/// The object for type.
/// </returns>
/// <param name='objectType'>
/// Object type.
/// </param>
/// <param name='onlyPooled'>
/// If true, it will only return an object if there is one currently pooled.
/// </param>
public GameObject GetObjectForType ( string objectType , bool onlyPooled )
{
for(int i=0; i<objectPrefabs.Length; i++)
{
GameObject prefab = objectPrefabs[i];
if(prefab.name == objectType)
{
if(pooledObjects[i].Count > 0)
{
GameObject pooledObject = pooledObjects[i][0];
pooledObjects[i].RemoveAt(0);
pooledObject.transform.parent = null;
pooledObject.SetActiveRecursively(true);
return pooledObject;
} else if(!onlyPooled) {
return Instantiate(objectPrefabs[i]) as GameObject;
}
break;
}
}
//If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
return null;
}
/// <summary>
/// Pools the object specified. Will not be pooled if there is no prefab of that type.
/// </summary>
/// <param name='obj'>
/// Object to be pooled.
/// </param>
public void PoolObject ( GameObject obj )
{
for ( int i=0; i<objectPrefabs.Length; i++)
{
if(objectPrefabs[i].name == obj.name)
{
obj.SetActiveRecursively(false);
obj.transform.parent = containerObject.transform;
pooledObjects[i].Add(obj);
return;
}
}
}
}
using UnityEngine;
using System.Collections;
public class SoundEffect : MonoBehaviour
{
/// <summary>
/// The sound source that will be played when the effect is started.
/// </summary>
public AudioSource soundSource;
/// <summary>
/// The sound clips that will randomly be played if there is more than 1.
/// </summary>
public AudioClip[] soundClips;
/// <summary>
/// The length of the effectin seconds.
/// </summary>
public float effectLength = 1f;
/// <summary>
/// Should the effect be pooled after its completed.
/// </summary>
public bool poolAfterComplete = true;
/// <summary>
/// Resets the effect.
/// </summary>
public virtual void ResetEffect ()
{
if(poolAfterComplete)
{
ObjectPool.instance.PoolObject(gameObject);
} else {
Destroy(gameObject);
}
}
/// <summary>
/// Starts the effect.
/// </summary>
public virtual void StartEffect ()
{
soundSource.PlayOneShot(soundClips[Random.Range(0,soundClips.Length)]);
StartCoroutine(WaitForCompletion());
}
public IEnumerator WaitForCompletion ()
{
//Wait for the effect to complete itself
yield return new WaitForSeconds(effectLength);
//Reset the now completed effect
ResetEffect();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment