add project files
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace OHM.UnityToolkit.Pooling
|
||||
{
|
||||
public class PooledObject : MonoBehaviour
|
||||
{
|
||||
private int poolId;
|
||||
|
||||
private bool _used;
|
||||
|
||||
public int PoolId => poolId;
|
||||
|
||||
public bool Used => _used;
|
||||
|
||||
public void Use()
|
||||
{
|
||||
_used = true;
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
_used = false;
|
||||
}
|
||||
|
||||
public void AddToPool(int poolId)
|
||||
{
|
||||
this.poolId = poolId;
|
||||
}
|
||||
|
||||
public void RemoveFromPool()
|
||||
{
|
||||
poolId = -1;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (poolId != -1)
|
||||
{
|
||||
Debug.LogWarning("Pooled object " + base.name
|
||||
+ "destroyed whereas not ready. You should not destroy a pooled , but use the PoolsManager");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59525edf21d054c959c2d7401e337332
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using OHM.UnityToolkit;
|
||||
|
||||
namespace OHM.UnityToolkit.Pooling
|
||||
{
|
||||
public class PoolsManager : UniqueInstance<PoolsManager>
|
||||
{
|
||||
[SerializeField]
|
||||
private Transform poolsContainer;
|
||||
|
||||
[SerializeField]
|
||||
private List<PreloadPrefab> preloadPrefabs;
|
||||
|
||||
private Dictionary<int, Pool> pools;
|
||||
|
||||
public static T InstantiatePrefab<T>(T prefab, Transform parent, Vector3 position, Quaternion rotation, bool startActive = false) where T : Component
|
||||
{
|
||||
PooledObject pooledPrefab = prefab.GetComponent<PooledObject>();
|
||||
if (pooledPrefab != null && Instance != null)
|
||||
{
|
||||
PooledObject instance = Instance.GetObjectFromPrefab(pooledPrefab, parent, position, rotation, startActive);
|
||||
return (instance != null) ? instance.GetComponent<T>() : null;
|
||||
}
|
||||
|
||||
T plain = UnityEngine.Object.Instantiate(prefab, position, rotation, parent);
|
||||
plain.gameObject.SetActive(startActive);
|
||||
return plain;
|
||||
}
|
||||
|
||||
public static void ReleasePooledObject(PooledObject pooledObject)
|
||||
{
|
||||
if (pooledObject != null)
|
||||
{
|
||||
pooledObject.Release();
|
||||
UnityEngine.Object.Destroy(pooledObject.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseObject(GameObject obj)
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerator DelayReleaseObject(GameObject go, float delay)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
ReleaseObject(go);
|
||||
}
|
||||
|
||||
public static void ReleaseAllPooledChildren(Transform parent)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PooledObject[] pooled = parent.GetComponentsInChildren<PooledObject>(true);
|
||||
for (int i = 0; i < pooled.Length; i++)
|
||||
{
|
||||
ReleasePooledObject(pooled[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void AwakeInstance()
|
||||
{
|
||||
pools = new Dictionary<int, Pool>();
|
||||
if (preloadPrefabs == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (PreloadPrefab preload in preloadPrefabs)
|
||||
{
|
||||
Pool pool = GetPoolFromPrefab(preload.prefab);
|
||||
GrowPool(pool, preload.prefab, preload.preloadCount);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetPrefabPoolId(PooledObject prefab)
|
||||
{
|
||||
return prefab.gameObject.GetInstanceID();
|
||||
}
|
||||
|
||||
private Pool GetPoolFromPrefab(PooledObject prefab)
|
||||
{
|
||||
int id = GetPrefabPoolId(prefab);
|
||||
Pool pool;
|
||||
if (!pools.TryGetValue(id, out pool))
|
||||
{
|
||||
pool = new Pool();
|
||||
pool.id = id;
|
||||
pool.prefab = prefab;
|
||||
pools[id] = pool;
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
private Pool GetPoolId(int poolId)
|
||||
{
|
||||
Pool pool;
|
||||
pools.TryGetValue(poolId, out pool);
|
||||
return pool;
|
||||
}
|
||||
|
||||
private PooledObject GetObjectFromPrefab(PooledObject prefab, Transform parent, Vector3 position, Quaternion rotation, bool startActive = false)
|
||||
{
|
||||
Pool pool = GetPoolFromPrefab(prefab);
|
||||
PooledObject obj = null;
|
||||
if (pool.freeObjects.Count >= 1)
|
||||
{
|
||||
obj = pool.freeObjects[pool.freeObjects.Count - 1];
|
||||
pool.freeObjects.RemoveAt(pool.freeObjects.Count - 1);
|
||||
pool.usedObjets.Add(obj);
|
||||
obj.transform.SetParent(parent);
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
obj = InstantiateObjectForPool(pool, prefab, parent, startActive);
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
obj.transform.position = position;
|
||||
obj.transform.rotation = rotation;
|
||||
obj.gameObject.SetActive(startActive);
|
||||
obj.Use();
|
||||
return obj;
|
||||
}
|
||||
|
||||
private PooledObject InstantiateObjectForPool(Pool pool, PooledObject prefab, Transform parent, bool startActive = false)
|
||||
{
|
||||
bool wasActive = prefab.gameObject.activeSelf;
|
||||
if (wasActive)
|
||||
{
|
||||
prefab.gameObject.SetActive(false);
|
||||
}
|
||||
PooledObject obj = UnityEngine.Object.Instantiate(prefab, parent);
|
||||
if (wasActive)
|
||||
{
|
||||
prefab.gameObject.SetActive(true);
|
||||
}
|
||||
obj.AddToPool(pool.id);
|
||||
obj.name = prefab.name + "_" + pool.totalObjectsCount;
|
||||
pool.totalObjectsCount++;
|
||||
pool.usedObjets.Add(obj);
|
||||
if (startActive)
|
||||
{
|
||||
obj.gameObject.SetActive(true);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void GrowPool(Pool pool, PooledObject prefab, int num)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
ReleaseObject(InstantiateObjectForPool(pool, prefab, poolsContainer));
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseObject(PooledObject pooledObject)
|
||||
{
|
||||
if (pooledObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!pooledObject.Used)
|
||||
{
|
||||
Debug.LogWarning("Releasing a non used object");
|
||||
return;
|
||||
}
|
||||
Pool pool = GetPoolId(pooledObject.PoolId);
|
||||
if (pool == null)
|
||||
{
|
||||
Debug.LogWarning("Releasing used object but no pool found");
|
||||
return;
|
||||
}
|
||||
if (pool.usedObjets.Contains(pooledObject))
|
||||
{
|
||||
pool.usedObjets.Remove(pooledObject);
|
||||
}
|
||||
pool.freeObjects.Add(pooledObject);
|
||||
pooledObject.Release();
|
||||
pooledObject.gameObject.SetActive(false);
|
||||
pooledObject.transform.SetParent(poolsContainer);
|
||||
}
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
private void Clear()
|
||||
{
|
||||
if (pools == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (KeyValuePair<int, Pool> entry in pools)
|
||||
{
|
||||
foreach (PooledObject free in entry.Value.freeObjects)
|
||||
{
|
||||
if (free != null)
|
||||
{
|
||||
free.RemoveFromPool();
|
||||
}
|
||||
}
|
||||
entry.Value.freeObjects.Clear();
|
||||
foreach (PooledObject used in entry.Value.usedObjets)
|
||||
{
|
||||
if (used != null)
|
||||
{
|
||||
used.RemoveFromPool();
|
||||
}
|
||||
}
|
||||
entry.Value.usedObjets.Clear();
|
||||
}
|
||||
pools.Clear();
|
||||
}
|
||||
|
||||
public void SaveCurrentToPreloading()
|
||||
{
|
||||
preloadPrefabs.Clear();
|
||||
foreach (KeyValuePair<int, Pool> entry in pools)
|
||||
{
|
||||
var preload = new PreloadPrefab();
|
||||
preload.prefab = entry.Value.prefab;
|
||||
preload.preloadCount = entry.Value.totalObjectsCount;
|
||||
preloadPrefabs.Add(preload);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class PreloadPrefab
|
||||
{
|
||||
public PooledObject prefab;
|
||||
|
||||
public int preloadCount;
|
||||
|
||||
}
|
||||
|
||||
private class Pool
|
||||
{
|
||||
public int id = -1;
|
||||
|
||||
public PooledObject prefab;
|
||||
|
||||
public List<PooledObject> freeObjects = new List<PooledObject>();
|
||||
|
||||
public HashSet<PooledObject> usedObjets = new HashSet<PooledObject>();
|
||||
|
||||
public int totalObjectsCount;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70aed98ea9388773529f2508969a5d6c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user