Unity中实现一个对象池
作者:互联网
这里写目录标题
一、对象池流程图
-
总池子
将总池子作为单例模式供外部调用,管理具体的子池子。 -
子池子
子池子中含有取池子中的对象,回收池子中的对象,两个功能。 -
ReusableObject脚本
该脚本是池子中的对象需要继承它,根据实际情况对实现具体的逻辑,需要实现的方法OnSpawn()
、OnUnSpawn()
,调用是根据消息机制进行调用,在子池子中声明取和放回分别调用对应的方法。 -
IReusable 接口类
OnSpawn() 取物体时调用
OnUnSpawn() 回收物体时调用
二、案例
总池子
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 总池子
/// </summary>
public class ObjectPool :MonoBehaviour
{
/// <summary>
/// 资源目录
/// </summary>
public string ResourcesDir = "";
Dictionary<string, SubPool> m_pools = new Dictionary<string, SubPool>();
private static OvjectPool Instance;
void Awake()
{
if(Instance==null)
Instance=this;
}
/// <summary>
/// 取物体
/// </summary>
/// <param name="name"></param>
public GameObject Spawn(string name,Transform parent)
{
SubPool subPool = null;
if (!m_pools.ContainsKey(name))
{
RegieterNew(name,parent);
}
subPool = m_pools[name];
return subPool.Spawn();
}
/// <summary>
/// 回收物体
/// </summary>
/// <param name="go"></param>
public void UnSpawn(GameObject go)
{
SubPool subPool = null;
foreach (var p in m_pools.Values)
{
if (p.Contain(go))
{
subPool = p;
break;
}
}
subPool.UnSpawn(go);
}
/// <summary>
/// 回收所有
/// </summary>
public void UnSpwanAll()
{
foreach (var p in m_pools.Values)
{
p.UnSpawnAll();
}
}
/// <summary>
/// 如果没有则新建一个池子
/// </summary>
/// <param name="name">资源名字</param>
/// <param name="parent">所存在的父物体</param>
private void RegieterNew(string name,Transform parent)
{
string path = ResourcesDir + "/" + name;
GameObject go = Resources.Load<GameObject>(path);
//New一个新池子
SubPool pool = new SubPool(parent, go);
//加入字典中
m_pools.Add(pool.Name, pool);
}
}
子池子
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SubPool
{
List<GameObject> m_objects = new List<GameObject>();
//预设
GameObject m_prefab;
//名字
public string Name {
get {
return m_prefab.name;
}
}
//父物体
Transform m_parent;
//构造方法
public SubPool(Transform parent,GameObject go)
{
m_parent = parent;
m_prefab = go;
}
public GameObject Spawn()
{
GameObject go = null;
foreach (var obj in m_objects)
{
if (!obj.activeSelf)
{
go = obj;
}
}
if (go=null)
{
//生成一个新的游戏物体
go = GameObject.Instantiate<GameObject>(m_prefab);
go.transform.parent = m_parent;
m_objects.Add(go);
}
go.SetActive(true);
go.SendMessage("OnSpawn", SendMessageOptions.DontRequireReceiver); //如果有这个方法就调用 没有不报错
return go;
}
/// <summary>
/// 回收物体
/// </summary>
public void UnSpawn(GameObject go)
{
if (m_objects.Contains(go))
{
go.SendMessage("OnUnSpawn",SendMessageOptions.DontRequireReceiver);
go.SetActive(false);
}
}
/// <summary>
/// 回收所有的物体
/// </summary>
public void UnSpawnAll()
{
foreach (var obj in m_objects)
{
if (obj.activeSelf)
{
UnSpawn(obj);
}
}
}
/// <summary>
/// 判断是否存在
/// </summary>
/// <param name="go"></param>
/// <returns></returns>
public bool Contain(GameObject go)
{
if (m_objects.Contains(go))
{
return true;
}
return false;
}
}
池子中的对象需要继承实现
如果池子中的对象有数据,可以在取和回收对象的时候做一些数据的初始化操作
using UnityEngine;
public abstract class ReusableObject : MonoBehaviour, IReusable
{
public abstract void OnSpawn();
public abstract void OnUnSpawn();
}
IReusable 接口类
public interface IReusable
{
/// <summary>
/// 取出时候调用
/// </summary>
void OnSpawn();
/// <summary>
/// 回收时候调用
/// </summary>
void OnUnSpawn();
}
测试
标签:parent,对象,GameObject,void,池子,实现,Unity,go,public 来源: https://blog.csdn.net/weixin_44446603/article/details/115473794