简介
之前对象池都是自己写,现在unity的API自带对象池了,UnityEngine.Pool 官方文档:https://docs.unity3d.com/ScriptReference/Pool.CollectionPool_2.html 主要包含了几个类
1.CollectionPool<T0,T1> 集合池,可以放List、HashSet、Dictionary啥的,非线程安全
2.DictionaryPool<T0,T1> 字典池,继承自CollectionPool
3.GenericPool< T0 > 通用池,ObjectPool的静态实现,启用了集合检查,以确保不会重复回收。非线程安全
4.HashSetPool< T0> 哈希集池,CollectionPool<T0,T1>的HashSet版本。
5.LinkedPool< T0> 链表池,IObjectPool的链表版本,池子内的对象是以链表形式保存的,非线程安全
6.ListPool< T0> 列表池,CollectionPool<T0,T1>的list版本。
7.ObjectPool< T0> 对象池,基于堆栈的IObjectPool< T0>,池子内的对象是以堆栈的形式保存的,非线程安全
8.UnsafeGenericPool< T0> 不安全通用池,提供ObjectPool的静态实现,这是禁用集合检查的GenericPool的替代方法。某些对象在收集检查期间进行比较时会产生垃圾。此版本不执行任何收集检查,因此不会产生垃圾。注意这不是线程安全的。
使用
官方案例,主要是unity的粒子系统来用对象池
using System.Text;
using UnityEngine;
using UnityEngine.Pool;
// 当粒子系统stop时,对象池回收,直接release
[RequireComponent(typeof(ParticleSystem))]
public class ReturnToPool : MonoBehaviour
{
public ParticleSystem system;
public IObjectPool<ParticleSystem> pool;
void Start()
{
system = GetComponent<ParticleSystem>();
var main = system.main;
main.stopAction = ParticleSystemStopAction.Callback;
}
void OnParticleSystemStopped()
{
// Return to the pool
pool.Release(system);
}
}
// This example spans a random number of ParticleSystems using a pool so that old systems can be reused.
public class PoolExample : MonoBehaviour
{
public enum PoolType
{
Stack,
LinkedList
}
public PoolType poolType;
// Collection checks will throw errors if we try to release an item that is already in the pool.
public bool collectionChecks = true;
public int maxPoolSize = 10;
IObjectPool<ParticleSystem> m_Pool;
public IObjectPool<ParticleSystem> Pool
{
get
{
if (m_Pool == null)
{
if (poolType == PoolType.Stack)
m_Pool = new ObjectPool<ParticleSystem>(CreatePooledItem, OnTakeFromPool, OnReturnedToPool, OnDestroyPoolObject, collectionChecks, 10, maxPoolSize);
else
m_Pool = new LinkedPool<ParticleSystem>(CreatePooledItem, OnTakeFromPool, OnReturnedToPool, OnDestroyPoolObject, collectionChecks, maxPoolSize);
}
return m_Pool;
}
}
ParticleSystem CreatePooledItem()
{
var go = new GameObject("Pooled Particle System");
var ps = go.AddComponent<ParticleSystem>();
ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
var main = ps.main;
main.duration = 1;
main.startLifetime = 1;
main.loop = false;
// This is used to return ParticleSystems to the pool when they have stopped.
var returnToPool = go.AddComponent<ReturnToPool>();
returnToPool.pool = Pool;
return ps;
}
// Called when an item is returned to the pool using Release
void OnReturnedToPool(ParticleSystem system)
{
system.gameObject.SetActive(false);
}
// Called when an item is taken from the pool using Get
void OnTakeFromPool(ParticleSystem system)
{
system.gameObject.SetActive(true);
}
// If the pool capacity is reached then any items returned will be destroyed.
// We can control what the destroy behavior does, here we destroy the GameObject.
void OnDestroyPoolObject(ParticleSystem system)
{
Destroy(system.gameObject);
}
void OnGUI()
{
GUILayout.Label("Pool size: " + Pool.CountInactive);
if (GUILayout.Button("Create Particles"))
{
var amount = Random.Range(1, 10);
for (int i = 0; i < amount; ++i)
{
var ps = Pool.Get();
ps.transform.position = Random.insideUnitSphere * 10;
ps.Play();
}
}
}
}