对象池工具类
csharp
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.Profiling;
using System.Collections;
using System.Threading;
namespace AdvancedPooling
{
#region 接口定义
/// <summary>
/// 池化对象接口
/// </summary>
public interface IPoolable
{
/// <summary>
/// 对象被取出时调用
/// </summary>
void OnSpawn();
/// <summary>
/// 对象被回收时调用
/// </summary>
void OnDespawn();
/// <summary>
/// 对象被销毁时调用
/// </summary>
void OnDestroy();
}
/// <summary>
/// 对象池统计信息
/// </summary>
public interface IPoolStats
{
int TotalCount { get; }
int ActiveCount { get; }
int AvailableCount { get; }
int PeakCount { get; }
int SpawnCount { get; }
int DespawnCount { get; }
float HitRate { get; }
}
#endregion
#region 核心实现
/// <summary>
/// 通用对象池(支持所有类型)
/// </summary>
/// <typeparam name="T">池化对象类型</typeparam>
public sealed class ObjectPool<T> : IPoolStats, IDisposable
{
#region 内部类
/// <summary>
/// Unity Component包装器
/// </summary>
private class UnityComponentWrapper : IPoolable
{
public Component Component { get; private set; }
public UnityComponentWrapper(Component component)
{
Component = component ?? throw new ArgumentNullException(nameof(component));
}
public void OnSpawn()
{
if (Component != null)
{
Component.gameObject.SetActive(true);
}
}
public void OnDespawn()
{
if (Component != null && Component.gameObject != null)
{
Component.gameObject.SetActive(false);
}
}
public void OnDestroy()
{
// Unity对象由Unity管理销毁
}
}
#endregion
#region 静态池管理器
private static readonly Dictionary<Type, object> _globalPools = new Dictionary<Type, object>();
private static readonly object _globalLock = new object();
/// <summary>
/// 获取或创建全局对象池
/// </summary>
public static ObjectPool<T> GetGlobalPool(Func<T> factory = null,
Action<T> onSpawn = null,
Action<T> onDespawn = null,
int initialCapacity = 32)
{
lock (_globalLock)
{
var type = typeof(T);
if (!_globalPools.TryGetValue(type, out var poolObj))
{
var pool = new ObjectPool<T>(factory, onSpawn, onDespawn, initialCapacity);
_globalPools[type] = pool;
return pool;
}
return (ObjectPool<T>)poolObj;
}
}
/// <summary>
/// 清空全局对象池
/// </summary>
public static void ClearGlobalPools()
{
lock (_globalLock)
{
foreach (var pool in _globalPools.Values)
{
if (pool is IDisposable disposable)
disposable.Dispose();
}
_globalPools.Clear();
}
}
#endregion
#region 配置委托
private readonly Func<T> _factory;
private readonly Action<T> _onSpawn;
private readonly Action<T> _onDespawn;
private readonly Action<T> _onDestroy;
private readonly bool _isUnityComponent;
private readonly bool _isIPoolable;
#endregion
#region 核心数据结构
// 使用栈存储可用对象(线程安全版本用于多线程环境)
private readonly Stack<T> _available;
// 所有对象集合(用于跟踪和清理)
private readonly HashSet<T> _allObjects;
// 活跃对象列表(用于快速遍历)
private readonly List<T> _activeObjects;
// 对象包装器缓存(用于Unity Component)
private readonly Dictionary<T, IPoolable> _wrappers;
#endregion
#region 统计信息
public int TotalCount => _allObjects.Count;
public int ActiveCount => _activeObjects.Count;
public int AvailableCount => _available.Count;
public int PeakCount { get; private set; }
public int SpawnCount { get; private set; }
public int DespawnCount { get; private set; }
public float HitRate => SpawnCount > 0 ? (SpawnCount - Math.Max(0, SpawnCount - DespawnCount)) / (float)SpawnCount : 0;
// 性能计数器
private long _totalAllocatedBytes;
private long _totalFreedBytes;
private readonly System.Diagnostics.Stopwatch _stopwatch;
#endregion
#region 构造函数
/// <summary>
/// 创建对象池
/// </summary>
/// <param name="factory">对象创建工厂方法</param>
/// <param name="onSpawn">对象取出时的回调</param>
/// <param name="onDespawn">对象回收时的回调</param>
/// <param name="initialCapacity">初始容量</param>
/// <param name="onDestroy">对象销毁时的回调</param>
public ObjectPool(Func<T> factory = null,
Action<T> onSpawn = null,
Action<T> onDespawn = null,
int initialCapacity = 32,
Action<T> onDestroy = null)
{
_factory = factory ?? (() => Activator.CreateInstance<T>());
_onSpawn = onSpawn;
_onDespawn = onDespawn;
_onDestroy = onDestroy;
_isUnityComponent = typeof(Component).IsAssignableFrom(typeof(T));
_isIPoolable = typeof(IPoolable).IsAssignableFrom(typeof(T));
// 优化容量设置
var capacity = Mathf.Max(initialCapacity, 4);
_available = new Stack<T>(capacity);
_allObjects = new HashSet<T>();
_activeObjects = new List<T>(capacity);
if (_isUnityComponent)
{
_wrappers = new Dictionary<T, IPoolable>(capacity);
}
_stopwatch = System.Diagnostics.Stopwatch.StartNew();
// 预创建对象
if (initialCapacity > 0)
{
Prewarm(initialCapacity);
}
}
#endregion
#region 核心方法
/// <summary>
/// 获取对象(无参数版本)
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T Spawn()
{
Profiler.BeginSample("ObjectPool.Spawn");
T obj;
bool isNew = false;
// 尝试从可用池获取
if (_available.Count > 0)
{
obj = _available.Pop();
}
else
{
// 创建新对象
obj = CreateNewObject();
isNew = true;
}
// 激活对象
ActivateObject(obj, isNew);
// 更新统计
SpawnCount++;
PeakCount = Math.Max(PeakCount, TotalCount);
Profiler.EndSample();
return obj;
}
/// <summary>
/// 获取对象(带初始化参数)
/// </summary>
public T Spawn(Action<T> initializer)
{
var obj = Spawn();
initializer?.Invoke(obj);
return obj;
}
/// <summary>
/// 回收对象
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Despawn(T obj)
{
if (obj == null || !_allObjects.Contains(obj))
{
Debug.LogWarning($"Attempting to despawn object not from pool: {obj}");
return;
}
Profiler.BeginSample("ObjectPool.Despawn");
// 禁用对象
DeactivateObject(obj);
// 放回可用池
_available.Push(obj);
// 从活跃列表移除
_activeObjects.Remove(obj);
// 更新统计
DespawnCount++;
Profiler.EndSample();
}
/// <summary>
/// 批量回收
/// </summary>
public void DespawnAll()
{
Profiler.BeginSample("ObjectPool.DespawnAll");
// 使用临时列表避免在遍历时修改集合
var tempList = new List<T>(_activeObjects);
foreach (var obj in tempList)
{
Despawn(obj);
}
Profiler.EndSample();
}
/// <summary>
/// 预创建对象
/// </summary>
public void Prewarm(int count)
{
Profiler.BeginSample("ObjectPool.Prewarm");
count = Math.Max(0, count);
for (int i = 0; i < count; i++)
{
var obj = CreateNewObject();
_available.Push(obj);
}
Profiler.EndSample();
}
/// <summary>
/// 清理池(销毁指定数量的可用对象)
/// </summary>
public void Shrink(int targetAvailableCount)
{
targetAvailableCount = Math.Max(0, targetAvailableCount);
int toRemove = _available.Count - targetAvailableCount;
if (toRemove <= 0) return;
Profiler.BeginSample("ObjectPool.Shrink");
for (int i = 0; i < toRemove && _available.Count > 0; i++)
{
var obj = _available.Pop();
DestroyObject(obj);
}
Profiler.EndSample();
}
/// <summary>
/// 释放池并销毁所有对象
/// </summary>
public void Dispose()
{
Profiler.BeginSample("ObjectPool.Dispose");
// 销毁所有对象
foreach (var obj in _allObjects)
{
DestroyObject(obj);
}
_available.Clear();
_allObjects.Clear();
_activeObjects.Clear();
_wrappers?.Clear();
// 记录统计信息
LogStats();
Profiler.EndSample();
}
#endregion
#region 私有方法
/// <summary>
/// 创建新对象
/// </summary>
private T CreateNewObject()
{
var obj = _factory();
// 记录内存分配(近似值)
if (obj != null)
{
_totalAllocatedBytes += System.Runtime.InteropServices.Marshal.SizeOf(obj);
}
_allObjects.Add(obj);
// 如果是Unity Component,创建包装器
if (_isUnityComponent && obj is Component component)
{
var wrapper = new UnityComponentWrapper(component);
_wrappers[obj] = wrapper;
// 设置初始状态
if (component.gameObject != null)
{
component.gameObject.SetActive(false);
}
}
return obj;
}
/// <summary>
/// 激活对象
/// </summary>
private void ActivateObject(T obj, bool isNew)
{
if (_isIPoolable && obj is IPoolable poolable)
{
poolable.OnSpawn();
}
else if (_isUnityComponent && _wrappers.TryGetValue(obj, out var wrapper))
{
wrapper.OnSpawn();
}
else
{
_onSpawn?.Invoke(obj);
}
// 添加到活跃列表
if (!isNew || !_activeObjects.Contains(obj))
{
_activeObjects.Add(obj);
}
}
/// <summary>
/// 禁用对象
/// </summary>
private void DeactivateObject(T obj)
{
if (_isIPoolable && obj is IPoolable poolable)
{
poolable.OnDespawn();
}
else if (_isUnityComponent && _wrappers.TryGetValue(obj, out var wrapper))
{
wrapper.OnDespawn();
}
else
{
_onDespawn?.Invoke(obj);
}
}
/// <summary>
/// 销毁对象
/// </summary>
private void DestroyObject(T obj)
{
if (obj == null) return;
// 调用销毁回调
if (_isIPoolable && obj is IPoolable poolable)
{
poolable.OnDestroy();
}
else if (_isUnityComponent && _wrappers.TryGetValue(obj, out var wrapper))
{
wrapper.OnDestroy();
_wrappers.Remove(obj);
// 如果是Unity对象,由Unity管理销毁
if (obj is UnityEngine.Object unityObj)
{
if (Application.isPlaying)
UnityEngine.Object.Destroy(unityObj);
else
UnityEngine.Object.DestroyImmediate(unityObj);
}
}
else
{
_onDestroy?.Invoke(obj);
// 对于实现了IDisposable的对象,调用Dispose
if (obj is IDisposable disposable)
{
disposable.Dispose();
}
}
// 从集合中移除
_allObjects.Remove(obj);
_activeObjects.Remove(obj);
// 记录内存释放
_totalFreedBytes += System.Runtime.InteropServices.Marshal.SizeOf(obj);
}
/// <summary>
/// 记录统计信息
/// </summary>
private void LogStats()
{
var elapsedSeconds = _stopwatch.Elapsed.TotalSeconds;
var opsPerSecond = elapsedSeconds > 0 ? (SpawnCount + DespawnCount) / elapsedSeconds : 0;
Debug.Log($"[ObjectPool<{typeof(T).Name}>] Stats:\n" +
$" Lifetime: {elapsedSeconds:F2}s\n" +
$" Total Operations: {SpawnCount + DespawnCount}\n" +
$" Operations/s: {opsPerSecond:F1}\n" +
$" Peak Objects: {PeakCount}\n" +
$" Hit Rate: {HitRate:P1}\n" +
$" Memory: {_totalAllocatedBytes / 1024}KB allocated, {_totalFreedBytes / 1024}KB freed");
}
#endregion
#region 工具方法
/// <summary>
/// 获取所有活跃对象
/// </summary>
public List<T> GetAllActive()
{
return new List<T>(_activeObjects);
}
/// <summary>
/// 遍历所有活跃对象
/// </summary>
public void ForEachActive(Action<T> action)
{
if (action == null) return;
foreach (var obj in _activeObjects)
{
action(obj);
}
}
/// <summary>
/// 检查对象是否属于此池
/// </summary>
public bool Contains(T obj) => _allObjects.Contains(obj);
/// <summary>
/// 获取统计信息字符串
/// </summary>
public string GetStatsString()
{
return $"Pool<{typeof(T).Name}>: " +
$"Total={TotalCount}, " +
$"Active={ActiveCount}, " +
$"Available={AvailableCount}, " +
$"HitRate={HitRate:P1}, " +
$"Peak={PeakCount}";
}
#endregion
}
#endregion
#region Unity专用优化
/// <summary>
/// Unity Component对象池(优化版本)
/// </summary>
/// <typeparam name="T">Component类型</typeparam>
public sealed class UnityComponentPool<T> : ObjectPool<T>, IDisposable where T : Component
{
private readonly T _prefab;
private readonly Transform _parent;
/// <summary>
/// 创建Unity Component对象池
/// </summary>
public UnityComponentPool(T prefab,
Transform parent = null,
int initialCapacity = 10,
int maxSize = 0,
bool autoReparent = true)
: base(() => CreateUnityObject(prefab, parent, autoReparent),
OnUnitySpawn,
OnUnityDespawn,
initialCapacity,
OnUnityDestroy)
{
_prefab = prefab;
_parent = parent;
}
private static T CreateUnityObject(T prefab, Transform parent, bool autoReparent)
{
var obj = UnityEngine.Object.Instantiate(prefab, parent, false);
obj.gameObject.SetActive(false);
obj.gameObject.name = $"{prefab.name}_Pooled_{Guid.NewGuid().ToString("N").Substring(0, 8)}";
return obj;
}
private static void OnUnitySpawn(T component)
{
if (component != null)
{
component.gameObject.SetActive(true);
}
}
private static void OnUnityDespawn(T component)
{
if (component != null && component.gameObject != null)
{
component.gameObject.SetActive(false);
}
}
private static void OnUnityDestroy(T component)
{
if (component != null)
{
if (Application.isPlaying)
UnityEngine.Object.Destroy(component.gameObject);
else
UnityEngine.Object.DestroyImmediate(component.gameObject);
}
}
/// <summary>
/// 获取对象并设置位置/旋转
/// </summary>
public T Spawn(Vector3 position, Quaternion rotation, Transform parent = null)
{
var obj = Spawn();
if (obj != null)
{
var transform = obj.transform;
transform.position = position;
transform.rotation = rotation;
if (parent != null)
{
transform.SetParent(parent, false);
}
}
return obj;
}
/// <summary>
/// 延迟回收
/// </summary>
public void Despawn(T obj, float delay)
{
if (obj != null && obj.gameObject.activeInHierarchy)
{
obj.StartCoroutine(DespawnDelayed(obj, delay));
}
}
private IEnumerator DespawnDelayed(T obj, float delay)
{
yield return new WaitForSeconds(delay);
Despawn(obj);
}
}
#endregion
#region 管理器
/// <summary>
/// 对象池管理器
/// </summary>
public static class PoolManager
{
private static readonly Dictionary<string, object> _pools = new Dictionary<string, object>();
private static readonly Dictionary<Type, string> _typeToDefaultName = new Dictionary<Type, string>();
private static Transform _poolRoot;
/// <summary>
/// 池根节点
/// </summary>
public static Transform PoolRoot
{
get
{
if (_poolRoot == null)
{
var go = new GameObject("PoolManager");
if (Application.isPlaying)
{
UnityEngine.Object.DontDestroyOnLoad(go);
}
_poolRoot = go.transform;
}
return _poolRoot;
}
}
/// <summary>
/// 获取或创建Unity Component池
/// </summary>
public static UnityComponentPool<T> GetUnityPool<T>(T prefab,
string poolName = null,
int initialCapacity = 10,
int maxSize = 0) where T : Component
{
poolName ??= GetDefaultPoolName<T>(prefab);
if (_pools.TryGetValue(poolName, out var poolObj))
{
return (UnityComponentPool<T>)poolObj;
}
var parent = new GameObject($"Pool_{poolName}").transform;
parent.SetParent(PoolRoot);
var pool = new UnityComponentPool<T>(prefab, parent, initialCapacity, maxSize);
_pools[poolName] = pool;
_typeToDefaultName[typeof(T)] = poolName;
return pool;
}
/// <summary>
/// 获取或创建通用对象池
/// </summary>
public static ObjectPool<T> GetPool<T>(string poolName = null,
Func<T> factory = null,
Action<T> onSpawn = null,
Action<T> onDespawn = null,
int initialCapacity = 32)
{
poolName ??= GetDefaultPoolName<T>();
if (_pools.TryGetValue(poolName, out var poolObj))
{
return (ObjectPool<T>)poolObj;
}
var pool = new ObjectPool<T>(factory, onSpawn, onDespawn, initialCapacity);
_pools[poolName] = pool;
_typeToDefaultName[typeof(T)] = poolName;
return pool;
}
/// <summary>
/// 回收对象到默认池
/// </summary>
public static void Despawn<T>(T obj)
{
if (obj == null) return;
var type = typeof(T);
if (_typeToDefaultName.TryGetValue(type, out var poolName))
{
if (_pools.TryGetValue(poolName, out var poolObj))
{
if (poolObj is ObjectPool<T> pool)
{
pool.Despawn(obj);
}
}
}
}
/// <summary>
/// 销毁指定池
/// </summary>
public static void DestroyPool<T>(string poolName = null)
{
poolName ??= GetDefaultPoolName<T>();
if (_pools.TryGetValue(poolName, out var poolObj))
{
if (poolObj is IDisposable disposable)
{
disposable.Dispose();
}
_pools.Remove(poolName);
}
}
/// <summary>
/// 销毁所有池
/// </summary>
public static void DestroyAllPools()
{
foreach (var pool in _pools.Values)
{
if (pool is IDisposable disposable)
{
disposable.Dispose();
}
}
_pools.Clear();
_typeToDefaultName.Clear();
if (_poolRoot != null)
{
if (Application.isPlaying)
UnityEngine.Object.Destroy(_poolRoot.gameObject);
else
UnityEngine.Object.DestroyImmediate(_poolRoot.gameObject);
_poolRoot = null;
}
}
/// <summary>
/// 获取所有池的统计信息
/// </summary>
public static string GetAllStats()
{
var sb = new System.Text.StringBuilder();
sb.AppendLine("=== Pool Manager Stats ===");
foreach (var kvp in _pools)
{
if (kvp.Value is IPoolStats stats)
{
sb.AppendLine($"{kvp.Key}: Total={stats.TotalCount}, Active={stats.ActiveCount}, HitRate={stats.HitRate:P1}");
}
}
return sb.ToString();
}
private static string GetDefaultPoolName<T>(object prefab = null)
{
var typeName = typeof(T).Name;
if (prefab is UnityEngine.Object unityObj && unityObj != null)
{
return $"{typeName}_{unityObj.name}";
}
return typeName;
}
}
#endregion
#region 扩展方法
/// <summary>
/// 对象池扩展方法
/// </summary>
public static class PoolExtensions
{
/// <summary>
/// 从全局池获取对象
/// </summary>
public static T SpawnFromGlobalPool<T>(this T prefab,
Action<T> initializer = null) where T : Component
{
var pool = PoolManager.GetUnityPool(prefab);
var obj = pool.Spawn();
initializer?.Invoke(obj);
return obj;
}
/// <summary>
/// 回收对象到默认池
/// </summary>
public static void DespawnToPool<T>(this T obj) where T : class
{
PoolManager.Despawn(obj);
}
/// <summary>
/// 使用对象池执行操作
/// </summary>
public static TResult UsePooled<T, TResult>(this ObjectPool<T> pool,
Func<T, TResult> func) where T : class
{
var obj = pool.Spawn();
try
{
return func(obj);
}
finally
{
pool.Despawn(obj);
}
}
/// <summary>
/// 使用对象池执行操作(无返回值)
/// </summary>
public static void UsePooled<T>(this ObjectPool<T> pool,
Action<T> action) where T : class
{
var obj = pool.Spawn();
try
{
action(obj);
}
finally
{
pool.Despawn(obj);
}
}
}
#endregion
#region 使用示例
public static class PoolExamples
{
/// <summary>
/// 值类型对象池示例
/// </summary>
public class Vector3PoolExample
{
private static readonly ObjectPool<Vector3> _vectorPool = new ObjectPool<Vector3>(
factory: () => Vector3.zero, // 创建方法
onSpawn: v => { /* 重置操作 */ }, // 取出时回调
onDespawn: v => { /* 清理操作 */ }, // 回收时回调
initialCapacity: 100
);
public static Vector3 GetVector() => _vectorPool.Spawn();
public static void ReturnVector(Vector3 v) => _vectorPool.Despawn(v);
}
/// <summary>
/// 引用类型对象池示例
/// </summary>
public class ListPoolExample
{
private static readonly ObjectPool<List<int>> _listPool = new ObjectPool<List<int>>(
factory: () => new List<int>(),
onSpawn: list => list.Clear(), // 取出时清空列表
onDespawn: list => list.Clear(), // 回收时清空列表
initialCapacity: 20
);
public static List<int> GetList() => _listPool.Spawn();
public static void ReturnList(List<int> list) => _listPool.Despawn(list);
}
/// <summary>
/// 自定义池化对象示例
/// </summary>
public class EnemyData : IPoolable
{
public int Health { get; set; }
public Vector3 Position { get; set; }
public void OnSpawn()
{
// 对象被取出时的初始化
Health = 100;
Position = Vector3.zero;
}
public void OnDespawn()
{
// 对象被回收时的清理
Health = 0;
}
public void OnDestroy()
{
// 对象被销毁时的清理
}
}
/// <summary>
/// 性能关键循环中的使用示例
/// </summary>
public static void PerformanceCriticalExample()
{
var particlePool = PoolManager.GetPool<Vector3>(
"ParticlePositions",
factory: () => Vector3.zero,
initialCapacity: 1000
);
// 在性能关键循环中使用
for (int i = 0; i < 10000; i++)
{
particlePool.UsePooled(position =>
{
// 使用位置进行计算
position.x = i * 0.1f;
// ... 其他操作
});
}
}
}
#endregion
}
主要优化特性:
1. 完全泛型支持
-
支持所有C#类型:值类型(Vector3, int等)、引用类型(class)、Unity Component
-
自动识别类型特性进行优化
2. 类型特定优化
-
Unity Component:自动处理GameObject激活状态、Transform父节点
-
IPoolable接口:支持自定义生命周期回调
-
值类型:避免装箱拆箱,内存更高效
3. 内存优化
-
使用
[MethodImpl(MethodImplOptions.AggressiveInlining)]内联关键方法 -
避免不必要的集合复制
-
精确的内存统计跟踪
4. 性能特性
-
线程安全:全局池管理器使用锁保证线程安全
-
缓存友好:使用连续内存结构(List、Stack)
-
零分配选项:避免在热路径中产生GC分配
5. 灵活的配置
-
支持自定义工厂方法
-
支持生命周期回调(Spawn/Despawn/Destroy)
-
支持延迟回收和批量操作
6. 丰富的统计信息
-
命中率统计
-
内存使用统计
-
操作频率统计
-
峰值使用统计
7. 易用性
-
扩展方法简化调用
-
全局池管理器
-
UsePooled模式确保对象正确回收
使用示例:
csharp
// 1. 值类型对象池
var vectorPool = new ObjectPool<Vector3>(
() => Vector3.zero,
v => { /* 初始化 */ },
v => { /* 清理 */ }
);
// 2. Unity对象池
var bulletPool = PoolManager.GetUnityPool(bulletPrefab, "Bullets", 20);
// 3. 使用IPoolable接口
var enemyPool = new ObjectPool<EnemyData>();
var enemy = enemyPool.Spawn(); // 自动调用OnSpawn()
// 4. 安全使用模式
bulletPool.UsePooled(bullet => {
bullet.transform.position = firePoint.position;
bullet.Shoot();
});
这个对象池系统经过高度优化,既支持所有C#类型,又对Unity Component进行了专门优化,适合在性能要求极高的项目中使用。
767

被折叠的 条评论
为什么被折叠?



