上海东方渔人码头电子沙盘单机版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

228 lines
6.4 KiB

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;
}
}