Browse Source

RecyclablePool

master
coffee 6 months ago
parent
commit
4f39d9baea
  1. 2
      Assets/Unity-Tools/Core/EasyPool/Core/IRecyclable.cs
  2. 1
      Assets/Unity-Tools/Core/EasyPool/Core/RecyclablePoolConfig.cs
  3. 106
      Assets/Unity-Tools/Core/EasyPool/Editor/RecyclableGOPoolKitInspector.cs
  4. 3
      Assets/Unity-Tools/Core/EasyPool/Editor/RecyclableGOPoolKitInspector.cs.meta
  5. 3
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool.meta
  6. 51
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolKit.cs
  7. 3
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolKit.cs.meta
  8. 230
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolManagerBase.cs
  9. 3
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolManagerBase.cs.meta
  10. 49
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGameObjectPool.cs
  11. 3
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGameObjectPool.cs.meta
  12. 88
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableMonoBehaviour.cs
  13. 3
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableMonoBehaviour.cs.meta
  14. 387
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclablePoolBase.cs
  15. 3
      Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclablePoolBase.cs.meta
  16. 8
      Assets/Unity-Tools/Core/EasyPool/SimpleGOPool/SimpleGOPoolKit.cs
  17. 131
      Assets/Unity-Tools/Core/EasyPool/SimpleGOPool/SimpleGameObjectPool.cs
  18. 8
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool.meta
  19. 274
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/Button.prefab
  20. 7
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/Button.prefab.meta
  21. 33
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/ImageButton.cs
  22. 3
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/ImageButton.cs.meta
  23. 1082
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPool.unity
  24. 7
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPool.unity.meta
  25. 56
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPoolManager.cs
  26. 2
      Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPoolManager.cs.meta

2
Assets/Unity-Tools/Core/EasyPool/Core/IRecyclable.cs

@ -14,7 +14,7 @@
void OnObjectInit();
void OnObjectDeInit();
void OnObjectDestroyInit();
void OnObjectSpawn();

1
Assets/Unity-Tools/Core/EasyPool/Core/RecyclablePoolConfig.cs

@ -14,6 +14,7 @@ namespace Tools.EasyPoolKit
public PoolDespawnDestroyType DespawnDestroyType = PoolDespawnDestroyType.Default;
public int? MaxDespawnCount = null;
public PoolClearType ClearType = PoolClearType.Default;
/// 自动回收时间
public float? AutoClearTime = null;
public bool IsIgnoreTimeScale = false;
public object[] ExtraArgs = Array.Empty<object>();

106
Assets/Unity-Tools/Core/EasyPool/Editor/RecyclableGOPoolKitInspector.cs

@ -0,0 +1,106 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Tools.EasyPoolKit.Editor
{
[CustomEditor(typeof(RecyclableGOPoolKit))]
public class RecyclableGOPoolKitInspector : UnityEditor.Editor
{
private readonly HashSet<string> _poolIdsSet = new HashSet<string>();
public override void OnInspectorGUI()
{
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available only on runtime.", MessageType.Info);
return;
}
var poolMgr = target as RecyclableGOPoolKit;
if (poolMgr)
{
EditorGUILayout.LabelField("RecyclableGOPoolManager");
var poolsInfo = poolMgr.GetPoolsInfo();
EditorGUILayout.LabelField("GameObject Pool Count", poolsInfo.Count.ToString());
for (int i = 0; i < poolsInfo.Count; i++)
{
var poolInfo = poolsInfo[i];
DrawGameObjectPool(poolInfo);
}
}
Repaint();
}
private void DrawGameObjectPool(RecyclablePoolInfo poolInfo)
{
var ifLastOpened = _poolIdsSet.Contains(poolInfo.PoolId);
var ifCurOpened = EditorGUILayout.Foldout(ifLastOpened, poolInfo.PoolId);
if (ifCurOpened != ifLastOpened)
{
if (ifCurOpened)
{
_poolIdsSet.Add(poolInfo.PoolId);
}
else
{
_poolIdsSet.Remove(poolInfo.PoolId);
}
}
if (ifCurOpened)
{
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField("PoolId", poolInfo.PoolId);
EditorGUILayout.LabelField("ReferenceType", poolInfo.ReferenceType.ToString());
EditorGUILayout.LabelField("InitCreateCount", poolInfo.InitCreateCount.HasValue ? poolInfo.InitCreateCount.Value.ToString() : "-");
EditorGUILayout.LabelField("ReachMaxLimitType", poolInfo.ReachMaxLimitType.ToString());
if (poolInfo.ReachMaxLimitType != PoolReachMaxLimitType.Default)
{
EditorGUILayout.LabelField("MaxSpawnCount", poolInfo.MaxSpawnCount.HasValue ? poolInfo.MaxSpawnCount.Value.ToString() : "-");
}
EditorGUILayout.LabelField("DespawnDestroyType", poolInfo.DespawnDestroyType.ToString());
if (poolInfo.DespawnDestroyType == PoolDespawnDestroyType.DestroyToLimit)
{
EditorGUILayout.LabelField("MaxDespawnCount", poolInfo.MaxDespawnCount.HasValue ? poolInfo.MaxDespawnCount.Value.ToString() : "-");
}
EditorGUILayout.LabelField("ClearType", poolInfo.ClearType.ToString());
EditorGUILayout.LabelField("AutoClearTime", poolInfo.AutoClearTime.ToString());
EditorGUILayout.LabelField("IfIgnoreTimeScale", poolInfo.IsIgnoreTimeScale.ToString());
EditorGUILayout.LabelField("CachedObjectCount", poolInfo.CachedObjectCount.ToString());
EditorGUILayout.LabelField("UsedObjectCount", poolInfo.UsedObjectCount.ToString());
EditorGUILayout.LabelField("TotalObjectCount", poolInfo.TotalObjectCount.ToString());
if (GUILayout.Button("ClearUnusedObjects(Safe)"))
{
if (poolInfo.ExtraInfo is RecyclableGameObjectPool pool)
{
pool.ClearUnusedObjects();
}
}
if (GUILayout.Button("ClearPool(Unsafe)"))
{
if (poolInfo.ExtraInfo is RecyclableGameObjectPool pool)
{
pool.ClearAll();
}
}
//TODO Draw all Objects
}
EditorGUILayout.EndVertical();
EditorGUILayout.Separator();
}
}
}
}

3
Assets/Unity-Tools/Core/EasyPool/Editor/RecyclableGOPoolKitInspector.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4f91df83af2a4b1783596dc115062a57
timeCreated: 1735968672

3
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1b4c6592766748e9850e7f96f3242d3b
timeCreated: 1735963479

51
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolKit.cs

@ -0,0 +1,51 @@
using System;
using NUnit.Framework;
using UnityEngine;
namespace Tools.EasyPoolKit
{
public class RecyclableGOPoolKit : RecyclableGOPoolManagerBase
{
public static RecyclableGOPoolKit Instance
{
get
{
if (_instance == null)
{
var poolRoot = new GameObject("RecyclableGOPoolKit");
var cachedRoot = new GameObject("CachedRoot");
cachedRoot.transform.SetParent(poolRoot.transform, false);
cachedRoot.gameObject.SetActive(false);
_instance = poolRoot.AddComponent<RecyclableGOPoolKit>();
_instance.CachedRoot = cachedRoot.transform;
DontDestroyOnLoad(_instance.gameObject);
}
return _instance;
}
}
private static RecyclableGOPoolKit _instance;
private void Awake()
{
if (_instance != null)
{
Debug.LogError("EasyPoolKit == Don't attach RecyclableGOPoolManager on any object, use SimpleGOPoolManager.Instance instead!");
Destroy(gameObject);
}
}
public override RecyclablePoolConfig GetDefaultPrefabPoolConfig(string poolPrefix, GameObject prefabAsset, Func<RecyclableMonoBehaviour> spawnFunc)
{
Assert.IsNotNull(prefabAsset);
var poolConfig = new RecyclablePoolConfig()
{
ObjectType = RecycleObjectType.RecyclableGameObject,
ReferenceType = typeof(GameObject),
PoolId = $"RecyclableGOPool_{poolPrefix ?? string.Empty}_{prefabAsset.GetInstanceID()}",
SpawnFunc = spawnFunc,
};
return poolConfig;
}
}
}

3
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolKit.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8cff55e0843e4bd0875e328d0b7216d5
timeCreated: 1735965986

230
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolManagerBase.cs

@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
namespace Tools.EasyPoolKit
{
public abstract class RecyclableGOPoolManagerBase : MonoBehaviour
{
public string PoolPrefix = string.Empty;
/// 缓存根节点
protected Transform CachedRoot;
/// key: 预制体的HashID, value: 对应的预制体
private Dictionary<int, GameObject> _prefabTemplates = new Dictionary<int, GameObject>();
/// key: 预制体的HashID, value: 对应的对象池
private Dictionary<int, RecyclableGameObjectPool> _gameObjPools = new Dictionary<int, RecyclableGameObjectPool>();
/// key: 激活的物体实例的HashID, value: 对应的预制体的HashID
private List<RecyclablePoolInfo> _poolInfoList = new List<RecyclablePoolInfo>();
public List<RecyclablePoolInfo> GetPoolsInfo() => _poolInfoList;
private bool _ifAppQuit = false;
/// 检测是否已有对应的对象池
public bool IfPoolValid(int prefabHash) => _prefabTemplates.ContainsKey(prefabHash) && _gameObjPools.ContainsKey(prefabHash);
private void Update()
{
foreach (var poolPair in _gameObjPools)
{
var pool = poolPair.Value;
var deltaTime = pool.IsIgnoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime;
pool.OnPoolUpdate(deltaTime);
}
}
private void OnApplicationQuit()
{
_ifAppQuit = true;
}
private void OnDestroy()
{
if (!_ifAppQuit)
{
ClearAllPools(true);
}
}
public RecyclableGameObjectPool RegisterPrefab(GameObject prefabAsset, RecyclablePoolConfig config = null)
{
Assert.IsNotNull(prefabAsset);
var prefabHash = prefabAsset.GetInstanceID();
#if EASY_POOL_DEBUG
if (_gameObjPools.ContainsKey(prefabHash) || _prefabTemplates.ContainsKey(prefabHash))
{
Debug.LogError($"EasyPoolKit == RegisterPrefab {prefabAsset.name} but already registered");
return null;
}
#endif
if (config == null)
{
config = GetDefaultPrefabPoolConfig(PoolPrefix, prefabAsset, null);
}
if (config.SpawnFunc == null)
{
config.SpawnFunc = () => DefaultCreateObjectFunc(prefabHash);
}
if (config.ExtraArgs == null || config.ExtraArgs.Length == 0)
{
config.ExtraArgs = new object[] { CachedRoot };
}
_prefabTemplates[prefabHash] = prefabAsset;
var newPool = new RecyclableGameObjectPool(config);
_gameObjPools[prefabHash] = newPool;
_poolInfoList.Add(newPool.GetPoolInfoReadOnly());
return newPool;
}
public bool UnRegisterPrefab(int prefabHash)
{
_prefabTemplates.Remove(prefabHash);
if (_gameObjPools.TryGetValue(prefabHash, out var pool))
{
pool.ClearAll();
_poolInfoList.Remove(pool.GetPoolInfoReadOnly());
_gameObjPools.Remove(prefabHash);
return true;
}
return false;
}
public RecyclableMonoBehaviour SimpleSpawn(GameObject prefabTemplate)
{
if (prefabTemplate == null)
{
return null;
}
var prefabHash = prefabTemplate.GetInstanceID();
if (!_gameObjPools.TryGetValue(prefabHash, out var pool))
{
pool = RegisterPrefab(prefabTemplate);
}
return pool.SpawnObject();
}
public T SimpleSpawn<T>(GameObject prefabTemplate) where T :RecyclableMonoBehaviour
{
return SimpleSpawn(prefabTemplate) as T;
}
public bool TrySpawn(int prefabHash, out RecyclableMonoBehaviour recyclableObj)
{
recyclableObj = null;
if (_gameObjPools.TryGetValue(prefabHash, out var pool))
{
recyclableObj = pool.SpawnObject();
}
return recyclableObj != null;
}
public bool TrySpawn<T>(int prefabHash, out T recyclableObj) where T :RecyclableMonoBehaviour
{
recyclableObj = null;
if (TrySpawn(prefabHash, out var newObj))
{
recyclableObj = newObj as T;
return true;
}
return false;
}
public bool Despawn(RecyclableMonoBehaviour recyclableObj)
{
Assert.IsNotNull(recyclableObj);
return recyclableObj.DespawnSelf();
}
public bool ClearPoolByAssetHash(int prefabHash, bool onlyClearUnused = false)
{
if (_gameObjPools.TryGetValue(prefabHash, out var pool))
{
if (onlyClearUnused)
{
pool.ClearUnusedObjects();
return true;
}
else
{
pool.ClearAll();
return true;
}
}
return false;
}
public void ClearAllUnusedObjects()
{
foreach (var poolPair in _gameObjPools)
{
poolPair.Value.ClearUnusedObjects();
}
}
public void ClearAllPools(bool ifDestroy)
{
foreach (var pool in _gameObjPools)
{
pool.Value.ClearAll();
}
if (ifDestroy)
{
if (CachedRoot)
{
for (int i = CachedRoot.childCount - 1; i >= 0; i--)
{
var child = CachedRoot.GetChild(i).gameObject;
Destroy(child);
}
}
_prefabTemplates.Clear();
_poolInfoList.Clear();
_gameObjPools.Clear();
}
}
private RecyclableMonoBehaviour DefaultCreateObjectFunc(int prefabHash)
{
if (_prefabTemplates.TryGetValue(prefabHash, out var prefabAsset))
{
if (prefabAsset != null)
{
var gameObj = Instantiate(prefabAsset);
var recyclableObj = gameObj.GetOrCreateRecyclableMono();
recyclableObj.PrefabHash = prefabHash;
return recyclableObj;
}
}
Debug.LogError($"EasyPoolKit == Cannot create object: {prefabHash}");
return null;
}
public abstract RecyclablePoolConfig GetDefaultPrefabPoolConfig(string poolPrefix, GameObject prefabAsset,
Func<RecyclableMonoBehaviour> spawnFunc);
}
}

3
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGOPoolManagerBase.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8cde1003a7854925ac58c691ed66bdf9
timeCreated: 1735966230

49
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGameObjectPool.cs

@ -0,0 +1,49 @@
using UnityEngine;
namespace Tools.EasyPoolKit
{
public class RecyclableGameObjectPool : RecyclablePoolBase<RecyclableMonoBehaviour>
{
private Transform _cachedRoot;
public RecyclableGameObjectPool(RecyclablePoolConfig config) : base(config) { }
protected override void OnInitByParams(object[] args)
{
var extraArgs = args;
if (extraArgs != null && extraArgs.Length > 0 && extraArgs[0] is Transform root)
{
_cachedRoot = root;
}
else
{
Debug.LogError("EasyPoolKit == Create RecyclableMonoPool should input the root Transform in extraArgs[0]");
}
}
protected override void OnObjectInit(RecyclableMonoBehaviour usedObj)
{
usedObj.Pool = this;
usedObj.PoolId = PoolId;
}
protected override void OnObjectEnqueue(RecyclableMonoBehaviour usedObj)
{
usedObj.transform.SetParent(_cachedRoot, true);
}
protected override void OnObjectDequeue(RecyclableMonoBehaviour usedObj)
{
usedObj.transform.SetParent(null, true);
}
protected override void OnObjectDestoryInit(RecyclableMonoBehaviour usedObj)
{
if (usedObj)
{
Object.Destroy(usedObj.gameObject);
}
}
}
}

3
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableGameObjectPool.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6ab2cfde92374470825bf4ff3b0ac5a3
timeCreated: 1735964092

88
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableMonoBehaviour.cs

@ -0,0 +1,88 @@
using UnityEngine;
using UnityEngine.Assertions;
namespace Tools.EasyPoolKit
{
public class RecyclableMonoBehaviour : MonoBehaviour, IRecyclable
{
public bool EnableMessage = false;
public RecyclableGameObjectPool Pool { get; set; }
public static readonly string MessageOnInit = "OnObjectInit";
public static readonly string MessageOnDeInit = "OnObjectDeInit";
public static readonly string MessageOnSpawn = "OnObjectSpawn";
public static readonly string MessageOnDespawn = "OnObjectDespawn";
public RecycleObjectType ObjectType => RecycleObjectType.RecyclableGameObject;
public string PoolId { get; set; }
public int ObjectId { get; set; }
public string Name { get => gameObject.name; set => gameObject.name = value; }
public float UsedTime { get; set; }
public int PrefabHash { get; set; }
public virtual void OnObjectInit()
{
if (EnableMessage)
{
SendMessage(MessageOnInit, SendMessageOptions.DontRequireReceiver);
}
}
public virtual void OnObjectDestroyInit()
{
if (EnableMessage)
{
SendMessage(MessageOnDeInit, SendMessageOptions.DontRequireReceiver);
}
}
public virtual void OnObjectSpawn()
{
if (EnableMessage)
{
SendMessage(MessageOnSpawn, SendMessageOptions.DontRequireReceiver);
}
}
public virtual void OnObjectDespawn()
{
UsedTime = 0;
PrefabHash = 0;
if (EnableMessage)
{
SendMessage(MessageOnDespawn, SendMessageOptions.DontRequireReceiver);
}
}
public virtual void OnObjectUpdate(float deltaTime)
{
UsedTime += deltaTime;
}
public bool DespawnSelf()
{
return Pool.DespawnObject(this);
}
}
public static class RecyclableMonoBehaviourExt
{
public static RecyclableMonoBehaviour GetOrCreateRecyclableMono(this GameObject gameObj,
bool enableMessage = false)
{
Assert.IsNotNull(gameObj);
var recyclableMono = gameObj.GetComponent<RecyclableMonoBehaviour>();
if (recyclableMono)
{
return recyclableMono;
}
recyclableMono = gameObj.AddComponent<RecyclableMonoBehaviour>();
recyclableMono.EnableMessage = enableMessage;
return recyclableMono;
}
}
}

3
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclableMonoBehaviour.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cc3dd3e8963f45f198d01d5e6664032e
timeCreated: 1735963499

387
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclablePoolBase.cs

@ -0,0 +1,387 @@
using System;
using System.Collections.Generic;
namespace Tools.EasyPoolKit
{
public abstract class RecyclablePoolBase<T> : IRecyclablePool<T> where T : class, IRecyclable
{
protected Queue<T> CachedQueue { get; private set; }
protected LinkedList<T> UsedList { get; private set; }
private int _objectCounter = 0;
private bool _ifInit = false;
public RecycleObjectType ObjectType { get; private set;}
public Type ReferenceType { get; private set;}
public string PoolId { get; private set;}
public int? InitCreateCount { get; private set;}
public int? MaxSpawnCount { get; private set;}
public int? MaxDespawnCount { get; private set;}
public float? AutoClearTime { get; private set;}
public Func<object> SpawnFunc { get; set; }
public PoolReachMaxLimitType ReachMaxLimitType { get; private set;}
public PoolDespawnDestroyType DespawnDestroyType { get; private set;}
public PoolClearType ClearType { get; private set;}
public bool IsIgnoreTimeScale { get; private set;}
public int GetCachedObjectCount() => CachedQueue.Count;
public int GetUsedObjectCount() => UsedList.Count;
public int GetTotalObjectCount() => CachedQueue.Count + UsedList.Count;
protected readonly RecyclablePoolInfo PoolInfo;
public RecyclablePoolInfo GetPoolInfoReadOnly() => PoolInfo;
public RecyclablePoolBase(RecyclablePoolConfig config)
{
PoolInfo = InitByConfig(config);
}
protected virtual RecyclablePoolInfo InitByConfig(RecyclablePoolConfig config)
{
if (_ifInit)
{
throw new Exception("EasyEventPool == Already Init!");
}
if (config == null)
{
throw new Exception("EasyEventPool == config is null!");
}
ObjectType = config.ObjectType;
ReferenceType = config.ReferenceType;
PoolId = config.PoolId;
SpawnFunc = config.SpawnFunc ?? throw new Exception("EasyEventPool == config.SpawnFunc is null!");
ReachMaxLimitType = config.ReachMaxLimitType;
DespawnDestroyType = config.DespawnDestroyType;
ClearType = config.ClearType;
InitCreateCount = config.InitCreateCount;
MaxSpawnCount = config.MaxSpawnCount;
MaxDespawnCount = config.MaxDespawnCount;
AutoClearTime = config.AutoClearTime;
IsIgnoreTimeScale = config.IsIgnoreTimeScale;
var poolInfo = new RecyclablePoolInfo(config, GetCachedObjectCount, GetUsedObjectCount, GetTotalObjectCount, this);
CachedQueue = MaxSpawnCount.HasValue
? new Queue<T>(MaxSpawnCount.Value + 1)
: new Queue<T>();
UsedList = new LinkedList<T>();
OnInitByParams(config.ExtraArgs);
InitCachedPool();
_ifInit = true;
#if EASY_POOL_DEBUG
//Check if params are valid
if (ReachMaxLimitType == PoolReachMaxLimitType.RejectNull ||
ReachMaxLimitType == PoolReachMaxLimitType.RecycleOldest)
{
if (!(MaxSpawnCount.HasValue && MaxSpawnCount.Value > 0))
{
throw new Exception("MaxSpawnCount.Value should > 0");
}
}
if (DespawnDestroyType == PoolDespawnDestroyType.DestroyToLimit)
{
if (!(MaxDespawnCount.HasValue && MaxDespawnCount.Value > 0))
{
throw new Exception("MaxDespawnCount.Value should > 0");
}
}
if (MaxSpawnCount.HasValue && MaxDespawnCount.HasValue)
{
if (!(MaxDespawnCount.Value <= MaxSpawnCount.Value))
{
throw new Exception("MaxDespawnCount.Value should <= MaxSpawnCount.Value");
}
}
if (MaxSpawnCount.HasValue && InitCreateCount.HasValue)
{
if (!(InitCreateCount.Value <= MaxSpawnCount.Value))
{
throw new Exception("InitCreateCount.Value should <= MaxSpawnCount.Value");
}
}
#endif
return poolInfo;
}
public T SpawnObject()
{
T cachedObj = null;
if (GetCachedObjectCount() > 0)
{
cachedObj = CachedQueue.Dequeue();
}
else
{
bool ifReachLimit = false;
if (ReachMaxLimitType != PoolReachMaxLimitType.Default && MaxSpawnCount.HasValue)
{
ifReachLimit = GetTotalObjectCount() >= MaxSpawnCount.Value;
}
if (!ifReachLimit)
{
cachedObj = CreateObject();
}
else
{
switch (ReachMaxLimitType)
{
case PoolReachMaxLimitType.RecycleOldest:
cachedObj = RecycleOldestObject();
break;
case PoolReachMaxLimitType.Default:
//Impossible
case PoolReachMaxLimitType.RejectNull:
default:
//do nothing
break;
}
}
}
if (cachedObj != null)
{
OnObjectDequeue(cachedObj);
cachedObj.OnObjectSpawn();
UsedList.AddLast(cachedObj);
}
return cachedObj;
}
public bool TrySpawnObject(out T newObj)
{
newObj = SpawnObject();
return newObj != null;
}
public bool DespawnObject(T usedObj)
{
if (usedObj == null)
{
return false;
}
var usedNode = UsedList.Find(usedObj);
if (usedNode == null)
{
return false;
}
bool ifReachLimit = false;
if (DespawnDestroyType == PoolDespawnDestroyType.DestroyToLimit)
{
if (MaxDespawnCount.HasValue && GetTotalObjectCount() > MaxDespawnCount.Value)
{
ifReachLimit = true;
}
}
UsedList.Remove(usedNode);
usedObj.OnObjectDespawn();
if (ifReachLimit)
{
DestroyPoolObject(usedObj);
}
else
{
CachedQueue.Enqueue(usedObj);
OnObjectEnqueue(usedObj);
}
return true;
}
public void OnPoolUpdate(float deltaTime)
{
if (UsedList.Count > 0)
{
var beginNode = UsedList.First;
float collectTime = AutoClearTime ?? -1f;
while (beginNode != null)
{
var currentNode = beginNode;
beginNode = beginNode.Next;
var usedObj = currentNode.Value;
usedObj.OnObjectUpdate(deltaTime);
if (collectTime > 0 && usedObj.UsedTime >= collectTime)
{
DespawnObject(usedObj);
}
}
}
}
private void InitCachedPool()
{
if (!InitCreateCount.HasValue)
{
return;
}
var initCount = InitCreateCount.Value;
for (int i = 0; i < initCount; i++)
{
var cachedObj = CreateObject();
CachedQueue.Enqueue(cachedObj);
OnObjectEnqueue(cachedObj);
}
}
private T CreateObject()
{
_objectCounter++;
if (SpawnFunc?.Invoke() is T cachedObj)
{
cachedObj.PoolId = PoolId;
cachedObj.ObjectId = _objectCounter;
#if EASY_POOL_DEBUG
cachedObj.Name = $"{PoolId}_{cachedObj.ObjectId}";
#endif
OnObjectInit(cachedObj);
cachedObj.OnObjectInit();
}
#if EASY_POOL_DEBUG
else
{
throw new Exception($"EasyPoolKit == GenerateObject {PoolId} Should not be null!");
}
#endif
return cachedObj;
}
protected virtual void OnInitByParams(object[] args){}
protected abstract void OnObjectInit(T usedObj);
protected abstract void OnObjectEnqueue(T usedObj);
protected abstract void OnObjectDequeue(T usedObj);
protected abstract void OnObjectDestoryInit(T usedObj);
private T RecycleOldestObject()
{
var firstNode = UsedList.First;
UsedList.Remove(firstNode);
var oldestObj = firstNode.Value;
if (oldestObj != null)
{
oldestObj.OnObjectDespawn();
}
//As it is a free node, need not to add it to cachedQueue
return oldestObj;
}
private void DestroyPoolObject(T poolObj)
{
if (poolObj != null)
{
poolObj.OnObjectDestroyInit();
OnObjectDestoryInit(poolObj);
}
}
#region Clear
public void ClearUnusedObjects()
{
foreach (var cachedItem in CachedQueue)
{
DestroyPoolObject(cachedItem);
}
CachedQueue.Clear();
}
public void ClearAll()
{
switch (ClearType)
{
case PoolClearType.Default:
poolClearAll();
break;
case PoolClearType.ClearToLimit:
poolClearToLimit();
break;
}
void poolClearAll()
{
foreach (var cachedItem in CachedQueue)
{
DestroyPoolObject(cachedItem);
}
CachedQueue.Clear();
while (UsedList.Count > 0)
{
var firstNode = UsedList.First;
var firstObj = firstNode.Value;
UsedList.Remove(firstNode);
DestroyPoolObject(firstObj);
}
UsedList.Clear();
}
void poolClearToLimit()
{
if (!InitCreateCount.HasValue)
{
poolClearAll();
return;
}
poolClearRetain();
int removeCount = GetCachedObjectCount() - InitCreateCount.Value;
while (removeCount > 0)
{
removeCount--;
var cachedObj = CachedQueue.Dequeue();
DestroyPoolObject(cachedObj);
}
// 回收正在使用的物体
void poolClearRetain()
{
while (UsedList.Count > 0)
{
var firstNode = UsedList.First;
var firstObj = firstNode.Value;
DespawnObject(firstObj);
}
}
}
}
#endregion
#region Debug
public string GetDebugConfigInfo() => PoolInfo?.GetDebugConfigInfo() ?? string.Empty;
public string GetDebugRunningInfo() => PoolInfo?.GetDebugRunningInfo() ?? string.Empty;
#endregion
}
}

3
Assets/Unity-Tools/Core/EasyPool/RecyclableGOPool/RecyclablePoolBase.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2f64392ce63446c280cd10dee37231e8
timeCreated: 1735964418

8
Assets/Unity-Tools/Core/EasyPool/SimpleGOPool/SimpleGOPoolKit.cs

@ -45,6 +45,8 @@ namespace Tools.EasyPoolKit
private bool _ifAppQuit = false;
/// 检测是否已有对应的对象池
public bool IsPoolValid(int prefabHash) => _prefabTemplates.ContainsKey(prefabHash) && _gameObjPools.ContainsKey(prefabHash);
private void Awake()
{
@ -78,12 +80,6 @@ namespace Tools.EasyPoolKit
ClearAllPools(true);
}
}
/// 检测是否已有对应的对象池
public bool IsPoolValid(int prefabHash)
{
return _prefabTemplates.ContainsKey(prefabHash) && _gameObjPools.ContainsKey(prefabHash);
}
public SimpleGameObjectPool RegisterPrefab(GameObject prefabAsset, RecyclablePoolConfig config = null)
{

131
Assets/Unity-Tools/Core/EasyPool/SimpleGOPool/SimpleGameObjectPool.cs

@ -32,6 +32,7 @@ namespace Tools.EasyPoolKit
public int GetTotalObjectCount() => CachedQueue.Count + UsedList.Count;
protected RecyclablePoolInfo PoolInfo;
public RecyclablePoolInfo GetPoolInfoReadOnly() => PoolInfo;
public SimpleGameObjectPool(RecyclablePoolConfig config)
{
@ -130,7 +131,7 @@ namespace Tools.EasyPoolKit
protected virtual void OnObjectInit(GameObject usedObj){ }
protected virtual void OnObjectEnqueue(GameObject usedObj) => usedObj.transform.SetParent(_cachedRoot, true);
protected virtual void OnObjectDequeue(GameObject usedObj) => usedObj.transform.SetParent(null, true);
protected virtual void OnObjectDeInit(GameObject usedObj)
protected virtual void OnObjectDestroyInit(GameObject usedObj)
{
if (usedObj)
{
@ -279,28 +280,6 @@ namespace Tools.EasyPoolKit
return true;
}
public void ClearUnusedObjects()
{
foreach (var cachedItem in CachedQueue)
{
DestroyPoolObject(cachedItem);
}
CachedQueue.Clear();
}
public void ClearAll()
{
switch (ClearType)
{
case PoolClearType.Default:
PoolClearAll();
break;
case PoolClearType.ClearToLimit:
PoolClearToLimit();
break;
}
}
public void OnPoolUpdate(float deltaTime)
{
if (UsedList.Count > 0)
@ -326,79 +305,95 @@ namespace Tools.EasyPoolKit
}
}
public RecyclablePoolInfo GetPoolInfoReadOnly() => PoolInfo;
private void DestroyPoolObject(GameObject poolObj)
{
if (poolObj)
{
OnObjectDeInit(poolObj);
OnObjectDestroyInit(poolObj);
}
}
private void PoolClearAll()
#region Clear
public void ClearUnusedObjects()
{
foreach (var cachedItem in CachedQueue)
{
DestroyPoolObject(cachedItem);
}
CachedQueue.Clear();
}
while (UsedList.Count > 0)
public void ClearAll()
{
switch (ClearType)
{
var firstNode = UsedList.First;
var firstObj = firstNode.Value;
UsedList.Remove(firstNode);
DestroyPoolObject(firstObj);
case PoolClearType.Default:
poolClearAll();
break;
case PoolClearType.ClearToLimit:
poolClearToLimit();
break;
}
UsedList.Clear();
}
private void PoolClearToLimit()
{
if (!InitCreateCount.HasValue)
void poolClearAll()
{
PoolClearAll();
return;
}
PoolClearRetain();
foreach (var cachedItem in CachedQueue)
{
DestroyPoolObject(cachedItem);
}
CachedQueue.Clear();
int removeCount = GetCachedObjectCount() - InitCreateCount.Value;
while (UsedList.Count > 0)
{
var firstNode = UsedList.First;
var firstObj = firstNode.Value;
UsedList.Remove(firstNode);
DestroyPoolObject(firstObj);
}
while (removeCount > 0)
{
removeCount--;
var cachedObj = CachedQueue.Dequeue();
DestroyPoolObject(cachedObj);
UsedList.Clear();
}
}
/// 回收正在使用的物体
private void PoolClearRetain()
{
while (UsedList.Count > 0)
void poolClearToLimit()
{
var firstNode = UsedList.First;
var firstObj = firstNode.Value;
DespawnObject(firstObj);
}
}
if (!InitCreateCount.HasValue)
{
poolClearAll();
return;
}
poolClearRetain();
#region Debug
int removeCount = GetCachedObjectCount() - InitCreateCount.Value;
public string GetDebugConfigInfo()
{
return PoolInfo?.GetDebugConfigInfo() ?? string.Empty;
while (removeCount > 0)
{
removeCount--;
var cachedObj = CachedQueue.Dequeue();
DestroyPoolObject(cachedObj);
}
// 回收正在使用的物体
void poolClearRetain()
{
while (UsedList.Count > 0)
{
var firstNode = UsedList.First;
var firstObj = firstNode.Value;
DespawnObject(firstObj);
}
}
}
}
public string GetDebugRunningInfo()
{
return PoolInfo?.GetDebugRunningInfo() ?? string.Empty;
}
#endregion
#region Debug
public string GetDebugConfigInfo() => PoolInfo?.GetDebugConfigInfo() ?? string.Empty;
public string GetDebugRunningInfo() => PoolInfo?.GetDebugRunningInfo() ?? string.Empty;
#endregion
}
}

8
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 259a517e8654b99499c0f17a15beb06f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

274
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/Button.prefab

@ -0,0 +1,274 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &212430069314405427
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5249829104186841453}
- component: {fileID: 8202632885764616307}
- component: {fileID: 7186356064517121775}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5249829104186841453
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 212430069314405427}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6440907175184653233}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8202632885764616307
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 212430069314405427}
m_CullTransparentMesh: 1
--- !u!114 &7186356064517121775
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 212430069314405427}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Button
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &5635780241963879440
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6440907175184653233}
- component: {fileID: 3201388121702467737}
- component: {fileID: 4180124986893198757}
- component: {fileID: 54520249064627873}
- component: {fileID: -7838970888251817805}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6440907175184653233
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635780241963879440}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 5249829104186841453}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 91.5, y: -15}
m_SizeDelta: {x: 183, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3201388121702467737
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635780241963879440}
m_CullTransparentMesh: 1
--- !u!114 &4180124986893198757
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635780241963879440}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &54520249064627873
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635780241963879440}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 4180124986893198757}
m_OnClick:
m_PersistentCalls:
m_Calls: []
--- !u!114 &-7838970888251817805
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635780241963879440}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 74056c96f6b34045924a42030d0ba1f9, type: 3}
m_Name:
m_EditorClassIdentifier:
EnableMessage: 0
button: {fileID: 54520249064627873}

7
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/Button.prefab.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 42fa37d0d62c2c649ad2a46cd6042baa
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

33
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/ImageButton.cs

@ -0,0 +1,33 @@
using UnityEngine;
using UnityEngine.UI;
namespace Tools.EasyPoolKit.Demo
{
public class ImageButton : RecyclableMonoBehaviour
{
[SerializeField] private Button button;
public override void OnObjectInit()
{
base.OnObjectInit();
button.onClick.AddListener(OnClick);
}
public override void OnObjectSpawn()
{
base.OnObjectSpawn();
Debug.Log($"ImageButton Spawned {name}");
}
public override void OnObjectDespawn()
{
base.OnObjectDespawn();
Debug.Log($"ImageButton Despawn {name}");
}
private void OnClick()
{
Debug.Log($"Button Clicked {name}");
}
}
}

3
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/ImageButton.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 74056c96f6b34045924a42030d0ba1f9
timeCreated: 1735967055

1082
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPool.unity

File diff suppressed because it is too large Load Diff

7
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPool.unity.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f9a4efcfd104ae42a4bd7e35bc1d016
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

56
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPoolManager.cs

@ -0,0 +1,56 @@
using System;
using UnityEngine;
namespace Tools.EasyPoolKit.Demo
{
public class RecyclableGOPoolManager : MonoBehaviour
{
[SerializeField] private GameObject buttonPrefab;
[SerializeField] private Transform parent;
private void Awake()
{
var buttonConfig = new RecyclablePoolConfig()
{
ObjectType = RecycleObjectType.RecyclableGameObject,
ReferenceType = typeof(ImageButton),
PoolId = "ImageButtonPool",
InitCreateCount = 5,
ReachMaxLimitType = PoolReachMaxLimitType.RecycleOldest,
MaxSpawnCount = 10,
DespawnDestroyType = PoolDespawnDestroyType.DestroyToLimit,
MaxDespawnCount = 5,
ClearType = PoolClearType.ClearToLimit,
IsIgnoreTimeScale = false,
};
RecyclableGOPoolKit.Instance.RegisterPrefab(buttonPrefab, buttonConfig);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
var newImage = RecyclableGOPoolKit.Instance.SimpleSpawn<ImageButton>(buttonPrefab);
newImage.transform.SetParent(parent);
}
// else if (Input.GetKeyDown(KeyCode.S))
// {
// RecyclableGOPoolKit.Instance.Despawn("Image");
// }
// else if (Input.GetKeyDown(KeyCode.C))
// {
// RecyclableGOPoolKit.Instance.ClearAllPools(true);
// }
// else if (Input.GetKeyDown(KeyCode.Alpha1))
// {
// var newImage = RecyclableGOPoolKit.Instance.Spawn("Cube");
// newImage.transform.SetParent(null);
// }
// else if (Input.GetKeyDown(KeyCode.Alpha2))
// {
// RecyclableGOPoolKit.Instance.Despawn("Cube");
// }
}
}
}

2
Assets/Unity-Tools/Demo/EasyPoolKit/RecyclableGOPool/RecyclableGOPoolManager.cs.meta

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e8aaad6940cad364082cdb3406487a8d
Loading…
Cancel
Save