SuperAPI AI 工具集

tools-unity-object-pooling

编程与开发

查看项目

更新于 10-16 06:05

技能介绍

用途

对象池通过复用 GameObject 而不是反复实例化(Instantiate)和销毁(Destroy),减少 GC 压力并提升性能。适用于任何高频实例化的场景。

何时使用

  • 频繁生成的对象(子弹、粒子、敌人)
  • UI 列表项
  • 音频源
  • 网络消息
  • 任何高频实例化

主要能力

基础对象池

提供泛型池实现 ObjectPool<T>,包含创建、获取、释放、销毁回调,支持默认容量与最大容量,并在构造时预热池。暴露 CountActive、CountInactive、CountAll 统计属性。

Unity 内置池(2021+)

使用 UnityEngine.Pool 命名空间下的 ObjectPool<T>,通过 createFunc、actionOnGet、actionOnRelease、actionOnDestroy 回调构建,支持 collectionCheck、defaultCapacity、maxSize 参数。示例展示子弹生成器 ProjectileSpawner。

池化对象基类

PooledObject<T> 抽象基类持有 IObjectPool<T> 引用,提供 SetPool、ReturnToPool 方法以及可重写的 OnSpawn、OnDespawn 钩子,便于在生成与回收时重置状态。

多预制体池

PoolManager 单例使用字典维护 GameObject -> ObjectPool<GameObject> 映射,提供 Spawn、Despawn、PrewarmPool 方法,并为每个预制体创建独立的父节点组织层级。配套 PoolExtensions 扩展方法提供 SpawnPooled 与 DespawnPooled 语法糖。

组件池

ComponentPool<T> 针对 Component 类型封装池,适用于 UI 伤害数字等场景,示例为 DamageNumberPool。

集合池

  • ListPool<T>:池化 List<T>,提供 GetDisposable 返回可 using 的 PooledList<T> 结构体,作用域结束自动归还。
  • StringBuilderPool:池化 StringBuilder,提供 GetStringAndRelease 便捷方法。

音频池

AudioPool 池化 AudioSource,PlayOneShot 播放后通过协程在音频时长结束后自动归还。

性能考量

  • 预热策略:PoolWarmer 在加载时按配置预热池,数量较大时分帧执行。
  • 池统计:PoolStats 记录 Gets、Releases、Creates,计算命中率并输出日志。

使用方式

代码示例展示了从创建池、获取对象、释放对象到扩展方法调用的完整流程。核心模式为:创建时 SetActive(false),获取时 SetActive(true),释放时重置状态并 SetActive(false)。

适用场景

子弹、粒子、敌人、UI 列表项、伤害数字、音频源、网络消息等高频实例化对象。

限制与注意事项

  • 需设置合理的最大容量,避免池无限增长。
  • 应在释放时重置状态,而非获取时。
  • 场景切换时需清理池以释放内存。
  • 需跟踪预制体到池的映射,避免使用错误的池。
  • 对象未重置时需实现 OnDespawn/Reset。
  • 生成时对象仍处于激活状态时,应在创建回调而非获取回调中设置 SetActive。

最佳实践

  • 在加载界面预热池
  • 设置合适的最大容量
  • 在释放时重置状态
  • 使用组合(PooledObject 基类)
  • 跟踪池命中率以优化容量
  • 在 OnDisable 中释放以处理场景切换
  • 将非激活对象置于父节点下以组织层级
  • 可用时使用内置池(2021+)
  • 池化昂贵组件(粒子系统、音频)
  • 通过性能分析验证 GC 改善