mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
ObjectPool
ObjectPool
This commit is contained in:
@@ -1,5 +1,49 @@
|
|||||||
%YAML 1.1
|
%YAML 1.1
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &1672025513
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1672025514}
|
||||||
|
- component: {fileID: 1672025515}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: ObjectPool
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &1672025514
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1672025513}
|
||||||
|
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_Children: []
|
||||||
|
m_Father: {fileID: 3463045026180535779}
|
||||||
|
m_RootOrder: 6
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1672025515
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1672025513}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: bef095b963a40b54fa82ba105bd1e98e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
Limit: 100
|
||||||
--- !u!1 &3463045025307533287
|
--- !u!1 &3463045025307533287
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -290,6 +334,7 @@ Transform:
|
|||||||
- {fileID: 3463045025836799505}
|
- {fileID: 3463045025836799505}
|
||||||
- {fileID: 3463045026010536331}
|
- {fileID: 3463045026010536331}
|
||||||
- {fileID: 3463045025307533286}
|
- {fileID: 3463045025307533286}
|
||||||
|
- {fileID: 1672025514}
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 0
|
m_RootOrder: 0
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
using TEngine.Runtime;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Editor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(ObjectPoolManager))]
|
||||||
|
internal sealed class ObjectPoolManagerInspector : TEngineInspector
|
||||||
|
{
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
if (!EditorApplication.isPlaying)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectPoolManager.Instance.Helper.ObjectPools.Count == 0)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("No Runtime Data!");
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pool in ObjectPoolManager.Instance.Helper.ObjectPools)
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Space(20);
|
||||||
|
GUILayout.Label(pool.Key + ": " + pool.Value.Count);
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
GUI.enabled = pool.Value.Count > 0;
|
||||||
|
if (GUILayout.Button("Clear", EditorStyles.miniButton))
|
||||||
|
{
|
||||||
|
pool.Value.Clear();
|
||||||
|
}
|
||||||
|
GUI.enabled = true;
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a49fa7335fa305d4bbef4478b39ed39a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,180 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
public static partial class Utility
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// GameObject相关的实用函数。
|
||||||
|
/// </summary>
|
||||||
|
public static class GameObjectUtils
|
||||||
|
{
|
||||||
|
#region Static Method
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 克隆实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="original">初始对象</param>
|
||||||
|
/// <returns>克隆的新对象</returns>
|
||||||
|
public static T Clone<T>(T original) where T : Object
|
||||||
|
{
|
||||||
|
return Object.Instantiate(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 克隆实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="original">初始对象</param>
|
||||||
|
/// <param name="position">新对象的位置</param>
|
||||||
|
/// <param name="rotation">新对象的旋转</param>
|
||||||
|
/// <returns>克隆的新对象</returns>
|
||||||
|
public static T Clone<T>(T original, Vector3 position, Quaternion rotation) where T : Object
|
||||||
|
{
|
||||||
|
return Object.Instantiate(original, position, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 克隆实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="original">初始对象</param>
|
||||||
|
/// <param name="position">新对象的位置</param>
|
||||||
|
/// <param name="rotation">新对象的旋转</param>
|
||||||
|
/// <param name="parent">新对象的父物体</param>
|
||||||
|
/// <returns>克隆的新对象</returns>
|
||||||
|
public static T Clone<T>(T original, Vector3 position, Quaternion rotation, Transform parent)
|
||||||
|
where T : Object
|
||||||
|
{
|
||||||
|
return Object.Instantiate(original, position, rotation, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 克隆实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="original">初始对象</param>
|
||||||
|
/// <param name="parent">新对象的父物体</param>
|
||||||
|
/// <returns>克隆的新对象</returns>
|
||||||
|
public static T Clone<T>(T original, Transform parent) where T : Object
|
||||||
|
{
|
||||||
|
return Object.Instantiate(original, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 克隆实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="original">初始对象</param>
|
||||||
|
/// <param name="parent">新对象的父物体</param>
|
||||||
|
/// <param name="worldPositionStays">是否保持世界位置不变</param>
|
||||||
|
/// <returns>克隆的新对象</returns>
|
||||||
|
public static T Clone<T>(T original, Transform parent, bool worldPositionStays) where T : Object
|
||||||
|
{
|
||||||
|
return Object.Instantiate(original, parent, worldPositionStays);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 克隆 GameObject 实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="original">初始对象</param>
|
||||||
|
/// <param name="isUI">是否是UI对象</param>
|
||||||
|
/// <returns>克隆的新对象</returns>
|
||||||
|
public static GameObject CloneGameObject(GameObject original, bool isUI = false)
|
||||||
|
{
|
||||||
|
GameObject obj = Object.Instantiate(original);
|
||||||
|
obj.transform.SetParent(original.transform.parent);
|
||||||
|
if (isUI)
|
||||||
|
{
|
||||||
|
RectTransform rect = obj.rectTransform();
|
||||||
|
RectTransform originalRect = original.rectTransform();
|
||||||
|
rect.anchoredPosition3D = originalRect.anchoredPosition3D;
|
||||||
|
rect.sizeDelta = originalRect.sizeDelta;
|
||||||
|
rect.offsetMin = originalRect.offsetMin;
|
||||||
|
rect.offsetMax = originalRect.offsetMax;
|
||||||
|
rect.anchorMin = originalRect.anchorMin;
|
||||||
|
rect.anchorMax = originalRect.anchorMax;
|
||||||
|
rect.pivot = originalRect.pivot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj.transform.localPosition = original.transform.localPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.transform.localRotation = original.transform.localRotation;
|
||||||
|
obj.transform.localScale = original.transform.localScale;
|
||||||
|
obj.SetActive(true);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 杀死实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">实例对象</param>
|
||||||
|
public static void Kill(Object obj)
|
||||||
|
{
|
||||||
|
Object.Destroy(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 立即杀死实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">实例对象</param>
|
||||||
|
public static void KillImmediate(Object obj)
|
||||||
|
{
|
||||||
|
Object.DestroyImmediate(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 杀死一群实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="objs">实例集合</param>
|
||||||
|
public static void Kills<T>(List<T> objs) where T : Object
|
||||||
|
{
|
||||||
|
for (int i = 0; i < objs.Count; i++)
|
||||||
|
{
|
||||||
|
Object.Destroy(objs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
objs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 杀死一群实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">实例类型</typeparam>
|
||||||
|
/// <param name="objs">实例数组</param>
|
||||||
|
public static void Kills<T>(T[] objs) where T : Object
|
||||||
|
{
|
||||||
|
for (int i = 0; i < objs.Length; i++)
|
||||||
|
{
|
||||||
|
Object.Destroy(objs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GameObjectExt
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取RectTransform组件
|
||||||
|
/// </summary>
|
||||||
|
public static RectTransform rectTransform(this GameObject obj)
|
||||||
|
{
|
||||||
|
return obj.GetComponent<RectTransform>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取RectTransform组件
|
||||||
|
/// </summary>
|
||||||
|
public static RectTransform rectTransform(this MonoBehaviour mono)
|
||||||
|
{
|
||||||
|
return mono.GetComponent<RectTransform>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a631f70e55a4d419de768a51347edab
|
||||||
|
timeCreated: 1662280007
|
8
Assets/TEngine/Scripts/Runtime/ObjectPool.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/ObjectPool.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 18905312db3bc3d448630110b4a9bcd3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/TEngine/Scripts/Runtime/ObjectPool/Helper.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/ObjectPool/Helper.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eaa7867dbaa447e42b63eb98f3dd8687
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,221 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认的对象池管理器助手
|
||||||
|
/// </summary>
|
||||||
|
public sealed class DefaultObjectPoolHelper : IObjectPoolHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 对象池默认上限
|
||||||
|
/// </summary>
|
||||||
|
private int _limit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所有对象池
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, ObjectPool> ObjectPools { get; private set; } =
|
||||||
|
new Dictionary<string, ObjectPool>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化助手
|
||||||
|
/// </summary>
|
||||||
|
public DefaultObjectPoolHelper()
|
||||||
|
{
|
||||||
|
_limit = ObjectPoolManager.Instance.Limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ShutDown
|
||||||
|
/// </summary>
|
||||||
|
public void ShutDown()
|
||||||
|
{
|
||||||
|
ClearAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="allocItem">对象模板</param>
|
||||||
|
/// <param name="onAlloc">对象生成时初始化委托</param>
|
||||||
|
/// <param name="onRelease">对象回收时处理委托</param>
|
||||||
|
/// <param name="limit">对象池上限,等于0时,表示使用默认值</param>
|
||||||
|
public void RegisterPool(string name, GameObject allocItem, Action<GameObject> onAlloc,
|
||||||
|
Action<GameObject> onRelease, int limit)
|
||||||
|
{
|
||||||
|
if (allocItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
ObjectPools.Add(name, new ObjectPool(allocItem, limit <= 0 ? _limit : limit, onAlloc, onRelease));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("注册对象池失败:已存在对象池 " + name + " !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否存在指定名称的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>是否存在</returns>
|
||||||
|
public bool IsExistPool(string name)
|
||||||
|
{
|
||||||
|
return ObjectPools.ContainsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除已注册的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
public void UnRegisterPool(string name)
|
||||||
|
{
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
ObjectPools[name].Clear();
|
||||||
|
ObjectPools.Remove(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("移除对象池失败:不存在对象池 " + name + " !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象池中对象数量
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>对象数量</returns>
|
||||||
|
public int GetPoolCount(string name)
|
||||||
|
{
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
return ObjectPools[name].Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Warning("获取对象数量失败:不存在对象池 " + name + " !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>对象</returns>
|
||||||
|
public GameObject Alloc(string name)
|
||||||
|
{
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
return ObjectPools[name].Alloc();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("生成对象失败:不存在对象池 " + name + " !");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="target">对象</param>
|
||||||
|
public void Release(string name, GameObject target)
|
||||||
|
{
|
||||||
|
if (target == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
ObjectPools[name].Release(target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("回收对象失败:不存在对象池 " + name + " !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="targets">对象数组</param>
|
||||||
|
public void Releases(string name, GameObject[] targets)
|
||||||
|
{
|
||||||
|
if (targets == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < targets.Length; i++)
|
||||||
|
{
|
||||||
|
ObjectPools[name].Release(targets[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("回收对象失败:不存在对象池 " + name + " !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="targets">对象集合</param>
|
||||||
|
public void Releases(string name, List<GameObject> targets)
|
||||||
|
{
|
||||||
|
if (targets == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < targets.Count; i++)
|
||||||
|
{
|
||||||
|
ObjectPools[name].Release(targets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("回收对象失败:不存在对象池 " + name + " !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空指定的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
public void Clear(string name)
|
||||||
|
{
|
||||||
|
if (ObjectPools.ContainsKey(name))
|
||||||
|
{
|
||||||
|
ObjectPools[name].Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("清空对象池失败:不存在对象池 " + name + " !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有对象池
|
||||||
|
/// </summary>
|
||||||
|
public void ClearAll()
|
||||||
|
{
|
||||||
|
foreach (var pool in ObjectPools)
|
||||||
|
{
|
||||||
|
pool.Value.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7f19a0d9040fd24439a22aa1b33b1752
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 701b9bfeb6deef341a599f8d0f1ec080, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 对象池管理器的助手接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IObjectPoolHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 所有对象池
|
||||||
|
/// </summary>
|
||||||
|
Dictionary<string, ObjectPool> ObjectPools { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="allocItem">对象模板</param>
|
||||||
|
/// <param name="onAlloc">对象生成时初始化委托</param>
|
||||||
|
/// <param name="onRelease">对象回收时处理委托</param>
|
||||||
|
/// <param name="limit">对象池上限,等于0时,表示使用默认值</param>
|
||||||
|
void RegisterPool(string name, GameObject allocItem, Action<GameObject> onAlloc,
|
||||||
|
Action<GameObject> onRelease, int limit);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否存在指定名称的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>是否存在</returns>
|
||||||
|
bool IsExistPool(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除已注册的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
void UnRegisterPool(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象池中对象数量
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>对象数量</returns>
|
||||||
|
int GetPoolCount(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>对象</returns>
|
||||||
|
GameObject Alloc(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="target">对象</param>
|
||||||
|
void Release(string name, GameObject target);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="targets">对象数组</param>
|
||||||
|
void Releases(string name, GameObject[] targets);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="targets">对象集合</param>
|
||||||
|
void Releases(string name, List<GameObject> targets);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空指定的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
void Clear(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有对象池
|
||||||
|
/// </summary>
|
||||||
|
void ClearAll();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9f0af4beea5247d40a447b27c807de3a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 701b9bfeb6deef341a599f8d0f1ec080, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
106
Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs
Normal file
106
Assets/TEngine/Scripts/Runtime/ObjectPool/Helper/ObjectPool.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 对象池
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ObjectPool
|
||||||
|
{
|
||||||
|
private readonly GameObject _allocItem;
|
||||||
|
private readonly int _limit = 100;
|
||||||
|
private readonly Queue<GameObject> _objectQueue = new Queue<GameObject>();
|
||||||
|
private readonly Action<GameObject> _onAlloc;
|
||||||
|
private readonly Action<GameObject> _onRelease;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 对象数量
|
||||||
|
/// </summary>
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get { return _objectQueue.Count; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="allocItem"></param>
|
||||||
|
/// <param name="limit"></param>
|
||||||
|
/// <param name="onAlloc"></param>
|
||||||
|
/// <param name="onRelease"></param>
|
||||||
|
public ObjectPool(GameObject allocItem, int limit, Action<GameObject> onAlloc,
|
||||||
|
Action<GameObject> onRelease)
|
||||||
|
{
|
||||||
|
_allocItem = allocItem;
|
||||||
|
_limit = limit;
|
||||||
|
_onAlloc = onAlloc;
|
||||||
|
_onRelease = onRelease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>对象</returns>
|
||||||
|
public GameObject Alloc()
|
||||||
|
{
|
||||||
|
GameObject obj;
|
||||||
|
if (_objectQueue.Count > 0)
|
||||||
|
{
|
||||||
|
obj = _objectQueue.Dequeue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = Utility.GameObjectUtils.CloneGameObject(_allocItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.SetActive(true);
|
||||||
|
|
||||||
|
obj.transform.SetParent(null);
|
||||||
|
|
||||||
|
_onAlloc?.Invoke(obj);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">对象</param>
|
||||||
|
public void Release(GameObject obj)
|
||||||
|
{
|
||||||
|
if (_objectQueue.Count >= _limit)
|
||||||
|
{
|
||||||
|
_onRelease?.Invoke(obj);
|
||||||
|
|
||||||
|
Utility.GameObjectUtils.Kill(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj.SetActive(false);
|
||||||
|
|
||||||
|
_onRelease?.Invoke(obj);
|
||||||
|
|
||||||
|
_objectQueue.Enqueue(obj);
|
||||||
|
|
||||||
|
obj.transform.SetParent(ObjectPoolManager.Instance.gameObject.transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有对象
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
while (_objectQueue.Count > 0)
|
||||||
|
{
|
||||||
|
GameObject obj = _objectQueue.Dequeue();
|
||||||
|
if (obj)
|
||||||
|
{
|
||||||
|
Utility.GameObjectUtils.Kill(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 27382aff833de094e97dd246ad567aad
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 701b9bfeb6deef341a599f8d0f1ec080, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
129
Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs
Normal file
129
Assets/TEngine/Scripts/Runtime/ObjectPool/ObjectPoolManager.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 对象池管理器
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ObjectPoolManager : UnitySingleton<ObjectPoolManager>
|
||||||
|
{
|
||||||
|
private IObjectPoolHelper _helper;
|
||||||
|
|
||||||
|
public IObjectPoolHelper Helper => _helper;
|
||||||
|
|
||||||
|
public override int Priority => -1;
|
||||||
|
|
||||||
|
public override void Awake()
|
||||||
|
{
|
||||||
|
base.Awake();
|
||||||
|
_helper = new DefaultObjectPoolHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单个对象池上限
|
||||||
|
/// </summary>
|
||||||
|
[SerializeField] internal int Limit = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="allocItem">对象模板</param>
|
||||||
|
/// <param name="onAlloc">对象生成时初始化委托</param>
|
||||||
|
/// <param name="onRelease">对象回收时处理委托</param>
|
||||||
|
/// <param name="limit">对象池上限,等于0时,表示使用默认值</param>
|
||||||
|
public void RegisterPool(string name, GameObject allocItem, Action<GameObject> onAlloc = null,
|
||||||
|
Action<GameObject> onRelease = null, int limit = 0)
|
||||||
|
{
|
||||||
|
_helper.RegisterPool(name, allocItem, onAlloc, onRelease, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否存在指定名称的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>是否存在</returns>
|
||||||
|
public bool IsExistPool(string name)
|
||||||
|
{
|
||||||
|
return _helper.IsExistPool(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除已注册的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
public void UnRegisterPool(string name)
|
||||||
|
{
|
||||||
|
_helper.UnRegisterPool(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取对象池中对象数量
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>对象数量</returns>
|
||||||
|
public int GetPoolCount(string name)
|
||||||
|
{
|
||||||
|
return _helper.GetPoolCount(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <returns>对象</returns>
|
||||||
|
public GameObject Alloc(string name)
|
||||||
|
{
|
||||||
|
return _helper.Alloc(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="target">对象</param>
|
||||||
|
public void Release(string name, GameObject target)
|
||||||
|
{
|
||||||
|
_helper.Release(name, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="targets">对象数组</param>
|
||||||
|
public void Releases(string name, GameObject[] targets)
|
||||||
|
{
|
||||||
|
_helper.Releases(name, targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量回收对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
/// <param name="targets">对象集合</param>
|
||||||
|
public void Releases(string name, List<GameObject> targets)
|
||||||
|
{
|
||||||
|
_helper.Releases(name, targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空指定的对象池
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">对象池名称</param>
|
||||||
|
public void Clear(string name)
|
||||||
|
{
|
||||||
|
_helper.Clear(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有对象池
|
||||||
|
/// </summary>
|
||||||
|
public void ClearAll()
|
||||||
|
{
|
||||||
|
_helper.ClearAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bef095b963a40b54fa82ba105bd1e98e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Reference in New Issue
Block a user