ObjectPool.cs 对象池的实现
码云简单示例:https://gitee.com/xianglinlove/ObjectPool
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool : Singleton<ObjectPool>
{
// Resources目录
public string ResourceDir = "";
// 保存预设资源和子池子
Dictionary<string, SubPool> _pools = new Dictionary<string, SubPool>();
// 取 name是预设的名字
public GameObject Spawn(string name)
{
// 判断对应的子池子是否存在
// 不存在就创建一个子池子
// 然后返回
if(!_pools.ContainsKey(name))
RegistreNewPool(name);
SubPool pool = _pools[name];
return pool.Spawn();
}
// 回收
public void UnSpawn(GameObject go)
{
// 只回收池子中存在的对象
// 遍历字典,找到包含go的子池子
// 调用子池子的UnSpawn方法回收
SubPool subPool = null;
foreach (var pool in _pools.Values)
{
if (pool.Contains(go))
{
subPool = pool;
break;
}
}
if(subPool != null)
subPool.UnSpawn(go);
}
// 回收所有
public void UnSpawnAll()
{
if (_pools == null) return;
foreach (var subPool in _pools.Values)
{
subPool.UnSpawnAll();
}
}
// 创建新子池子
void RegistreNewPool(string name)
{
// 获取预设
string prefab = "";
if (string.IsNullOrEmpty(ResourceDir))
prefab = name;
else
prefab = ResourceDir + "/"+name;
// 加载预设
GameObject go = Resources.Load<GameObject>(prefab);
// 创建新池子
SubPool pool = new SubPool(transform,go);
_pools.Add(pool.Name,pool);
}
}
SubPool.cs 子对象池的实现
using System.Collections.Generic;
using UnityEngine;
public class SubPool
{
// 对象池管理
private Transform _parent;
// 预设
private GameObject _prefab;
// 池子
private List<GameObject> _objects = new List<GameObject>();
// 标识
public string Name
{
get { return _prefab.name; }
}
// 构造
public SubPool(Transform parent, GameObject prefab)
{
this._parent = parent;
this._prefab = prefab;
}
// 从池子中取对象
public GameObject Spawn()
{
GameObject go = null;
// 遍历池子,看是否存在未被使用的对象
foreach (GameObject obj in _objects)
{
if (!obj.activeSelf)
{
go = obj;
break;
}
}
// 如果池子中不存在未被使用的就需要根据prefab实例化一个GameObject出来
// 并将新的对象加入到池子当中
if (go == null)
{
go = UnityEngine.Object.Instantiate(_prefab);
go.transform.parent = _parent;
_objects.Add(go);
}
// 激活对象,并通过该对象发送消息
go.SetActive(true);
go.SendMessage("OnSpawn",SendMessageOptions.DontRequireReceiver); // 取出实例之后可能需要做一些操作,比如有些Player,可能有默认动画之类的
return go;
}
// 回收对象
public void UnSpawn(GameObject go)
{
// 只回收池子中存在的对象
if (Contains(go))
{
go.SendMessage("OnUnspawn", SendMessageOptions.DontRequireReceiver); // 回收对象的时候需要设置 对象的属性至初始值
go.SetActive(false);
}
}
// 回收所有对象
public void UnSpawnAll()
{
if (_objects == null) return;
// 只处理池子中所有标识为启用的对象
foreach (GameObject obj in _objects)
{
if(obj.activeSelf)
UnSpawn(obj);
}
}
public bool Contains(GameObject go)
{
return _objects.Contains(go);
}
}
接口 IReusable.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IReusable
{
// 当取出时调用
void OnSpawn(); // 根据子对象池中设置的消息通知 每一个Spawn出来的对象上须包含这样的函数用来接收消息
// 当回收时调用
void OnUnspawn();
}
可复用对象
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
// 可重用的抽象对象类,由其子类来实现方法
public abstract class ReusableObject : MonoBehaviour, IReusable
{
public abstract void OnSpawn(); // 子对象池Spawn出来的对象 都是需要继承自MonoBehavior的 需要使用Update Awake等函数
public abstract void OnUnspawn();
}