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();
}

测试

相关文章

类型转换 1、int转string 2、string转int 3、string转float ...
package main import s &quot;strings&quot; import...
类使用:实现一个people中有一个sayhi的方法调用功能,代码如...
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件...
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http:...