Created
February 22, 2016 17:43
-
-
Save zaun/d560559b3366dd5e001b to your computer and use it in GitHub Desktop.
Unity3D Pools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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