...
This commit is contained in:
228
Assets/JMO Assets/WarFX/Spawn System/CFX_SpawnSystem.cs
Normal file
228
Assets/JMO Assets/WarFX/Spawn System/CFX_SpawnSystem.cs
Normal file
@ -0,0 +1,228 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// Cartoon FX - (c) 2012-2016 Jean Moreno
|
||||
|
||||
// Spawn System:
|
||||
// Preload GameObject to reuse them later, avoiding to Instantiate them.
|
||||
// Very useful for mobile platforms.
|
||||
|
||||
public class CFX_SpawnSystem : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the next available preloaded Object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The next available preloaded Object.
|
||||
/// </returns>
|
||||
/// <param name='sourceObj'>
|
||||
/// The source Object from which to get a preloaded copy.
|
||||
/// </param>
|
||||
/// <param name='activateObject'>
|
||||
/// Activates the object before returning it.
|
||||
/// </param>
|
||||
static public GameObject GetNextObject(GameObject sourceObj, bool activateObject = true)
|
||||
{
|
||||
int uniqueId = sourceObj.GetInstanceID();
|
||||
|
||||
if(!instance.poolCursors.ContainsKey(uniqueId))
|
||||
{
|
||||
Debug.LogError("[CFX_SpawnSystem.GetNextObject()] Object hasn't been preloaded: " + sourceObj.name + " (ID:" + uniqueId + ")\n", instance);
|
||||
return null;
|
||||
}
|
||||
|
||||
int cursor = instance.poolCursors[uniqueId];
|
||||
GameObject returnObj = null;
|
||||
if(instance.onlyGetInactiveObjects)
|
||||
{
|
||||
int loop = cursor;
|
||||
while(true)
|
||||
{
|
||||
returnObj = instance.instantiatedObjects[uniqueId][cursor];
|
||||
instance.increasePoolCursor(uniqueId);
|
||||
cursor = instance.poolCursors[uniqueId];
|
||||
|
||||
if(returnObj != null && !returnObj.activeSelf)
|
||||
break;
|
||||
|
||||
//complete loop: no active instance available
|
||||
if(cursor == loop)
|
||||
{
|
||||
if(instance.instantiateIfNeeded)
|
||||
{
|
||||
Debug.Log("[CFX_SpawnSystem.GetNextObject()] A new instance has been created for \"" + sourceObj.name + "\" because no active instance were found in the pool.\n", instance);
|
||||
PreloadObject(sourceObj);
|
||||
var list = instance.instantiatedObjects[uniqueId];
|
||||
returnObj = list[list.Count-1];
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[CFX_SpawnSystem.GetNextObject()] There are no active instances available in the pool for \"" + sourceObj.name +"\"\nYou may need to increase the preloaded object count for this prefab?", instance);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnObj = instance.instantiatedObjects[uniqueId][cursor];
|
||||
instance.increasePoolCursor(uniqueId);
|
||||
}
|
||||
|
||||
if(activateObject && returnObj != null)
|
||||
returnObj.SetActive(true);
|
||||
|
||||
return returnObj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Preloads an object a number of times in the pool.
|
||||
/// </summary>
|
||||
/// <param name='sourceObj'>
|
||||
/// The source Object.
|
||||
/// </param>
|
||||
/// <param name='poolSize'>
|
||||
/// The number of times it will be instantiated in the pool (i.e. the max number of same object that would appear simultaneously in your Scene).
|
||||
/// </param>
|
||||
static public void PreloadObject(GameObject sourceObj, int poolSize = 1)
|
||||
{
|
||||
instance.addObjectToPool(sourceObj, poolSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads all the preloaded objects from a source Object.
|
||||
/// </summary>
|
||||
/// <param name='sourceObj'>
|
||||
/// Source object.
|
||||
/// </param>
|
||||
static public void UnloadObjects(GameObject sourceObj)
|
||||
{
|
||||
instance.removeObjectsFromPool(sourceObj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether all objects defined in the Editor are loaded or not.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if all objects are loaded; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
static public bool AllObjectsLoaded
|
||||
{
|
||||
get
|
||||
{
|
||||
return instance.allObjectsLoaded;
|
||||
}
|
||||
}
|
||||
|
||||
// INTERNAL SYSTEM ----------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static private CFX_SpawnSystem instance;
|
||||
|
||||
public GameObject[] objectsToPreload = new GameObject[0];
|
||||
public int[] objectsToPreloadTimes = new int[0];
|
||||
public bool hideObjectsInHierarchy = false;
|
||||
public bool spawnAsChildren = true;
|
||||
public bool onlyGetInactiveObjects = false;
|
||||
public bool instantiateIfNeeded = false;
|
||||
|
||||
private bool allObjectsLoaded;
|
||||
private Dictionary<int,List<GameObject>> instantiatedObjects = new Dictionary<int, List<GameObject>>();
|
||||
private Dictionary<int,int> poolCursors = new Dictionary<int, int>();
|
||||
|
||||
private void addObjectToPool(GameObject sourceObject, int number)
|
||||
{
|
||||
int uniqueId = sourceObject.GetInstanceID();
|
||||
|
||||
//Add new entry if it doesn't exist
|
||||
if(!instantiatedObjects.ContainsKey(uniqueId))
|
||||
{
|
||||
instantiatedObjects.Add(uniqueId, new List<GameObject>());
|
||||
poolCursors.Add(uniqueId, 0);
|
||||
}
|
||||
|
||||
//Add the new objects
|
||||
GameObject newObj;
|
||||
for(int i = 0; i < number; i++)
|
||||
{
|
||||
newObj = (GameObject)Instantiate(sourceObject);
|
||||
newObj.SetActive(false);
|
||||
|
||||
//Set flag to not destruct object
|
||||
CFX_AutoDestructShuriken[] autoDestruct = newObj.GetComponentsInChildren<CFX_AutoDestructShuriken>(true);
|
||||
foreach(CFX_AutoDestructShuriken ad in autoDestruct)
|
||||
{
|
||||
ad.OnlyDeactivate = true;
|
||||
}
|
||||
//Set flag to not destruct light
|
||||
CFX_LightIntensityFade[] lightIntensity = newObj.GetComponentsInChildren<CFX_LightIntensityFade>(true);
|
||||
foreach(CFX_LightIntensityFade li in lightIntensity)
|
||||
{
|
||||
li.autodestruct = false;
|
||||
}
|
||||
|
||||
instantiatedObjects[uniqueId].Add(newObj);
|
||||
|
||||
if(hideObjectsInHierarchy)
|
||||
newObj.hideFlags = HideFlags.HideInHierarchy;
|
||||
|
||||
if(spawnAsChildren)
|
||||
newObj.transform.parent = this.transform;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeObjectsFromPool(GameObject sourceObject)
|
||||
{
|
||||
int uniqueId = sourceObject.GetInstanceID();
|
||||
|
||||
if(!instantiatedObjects.ContainsKey(uniqueId))
|
||||
{
|
||||
Debug.LogWarning("[CFX_SpawnSystem.removeObjectsFromPool()] There aren't any preloaded object for: " + sourceObject.name + " (ID:" + uniqueId + ")\n", this.gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
//Destroy all objects
|
||||
for(int i = instantiatedObjects[uniqueId].Count - 1; i >= 0; i--)
|
||||
{
|
||||
GameObject obj = instantiatedObjects[uniqueId][i];
|
||||
instantiatedObjects[uniqueId].RemoveAt(i);
|
||||
GameObject.Destroy(obj);
|
||||
}
|
||||
|
||||
//Remove pool entry
|
||||
instantiatedObjects.Remove(uniqueId);
|
||||
poolCursors.Remove(uniqueId);
|
||||
}
|
||||
|
||||
private void increasePoolCursor(int uniqueId)
|
||||
{
|
||||
instance.poolCursors[uniqueId]++;
|
||||
if(instance.poolCursors[uniqueId] >= instance.instantiatedObjects[uniqueId].Count)
|
||||
{
|
||||
instance.poolCursors[uniqueId] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if(instance != null)
|
||||
Debug.LogWarning("CFX_SpawnSystem: There should only be one instance of CFX_SpawnSystem per Scene!\n", this.gameObject);
|
||||
|
||||
instance = this;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
allObjectsLoaded = false;
|
||||
|
||||
for(int i = 0; i < objectsToPreload.Length; i++)
|
||||
{
|
||||
PreloadObject(objectsToPreload[i], objectsToPreloadTimes[i]);
|
||||
}
|
||||
|
||||
allObjectsLoaded = true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user