Unity制作最简单好用的对象池

Unity制作最简单好用的对象池


之前找过各种对象池demo,综合找到个最简单好用的对象池写法,只需要一个脚本,参考原文

原文链接
对这个脚本小做点改动,可以自行扩展几个重载方法。上代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PoolManager
{
    /// <summary>
    /// 对象池
    /// </summary>
    private Dictionary<string, List<GameObject>> pool;

    /// <summary>
    /// 预设体
    /// </summary>
    private Dictionary<string, GameObject> prefabs;


    #region 单例
    private static PoolManager instance;
    private PoolManager()
    {
        pool = new Dictionary<string, List<GameObject>>();
        prefabs = new Dictionary<string, GameObject>();
    }
    public static PoolManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new PoolManager();
            }
            return instance;
        }
    }
    #endregion

    /// <summary>
    /// 从对象池中获取对象
    /// </summary>
    /// <param name="objName">Prefab的名字</param>
    /// <param name="position">生成时的位置</param>
    /// <param name="quaternion">生成时的四元数</param>
    /// <returns></returns>
    public GameObject GetObj(string objName, Vector3 position, Quaternion quaternion)
    {
        //结果对象
        GameObject result = null;
        //判断是否有该名字的对象池
        if (pool.ContainsKey(objName))
        {
            //对象池里有对象
            if (pool[objName].Count > 0)
            {
                //获取结果
                result = pool[objName][0];
                //激活对象
                result.transform.position = position;
                result.transform.rotation = quaternion;
                result.SetActive(true);
                //从池中移除该对象
                pool[objName].Remove(result);
                //返回结果
                return result;
            }
        }
        //如果没有该名字的对象池或者该名字对象池没有对象

        GameObject prefab = null;
        //如果已经加载过该预设体
        if (prefabs.ContainsKey(objName))
        {
            prefab = prefabs[objName];
        }
        else     //如果没有加载过该预设体
        {
            //加载预设体
            prefab = Resources.Load<GameObject>("Prefabs/" + objName);
            //更新字典
            prefabs.Add(objName, prefab);
        }

        //生成
        result = Object.Instantiate(prefab);
        result.transform.position = position;
        result.transform.rotation = quaternion;
        //改名(去除 Clone)
        result.name = objName;
        //返回
        return result;
    }

    /// <summary>
    /// 从对象池中获取对象
    /// </summary>
    /// <param name="objName">Prefab的名字</param>
    /// <param name="parent">生成时的父级</param>
    /// <returns></returns>
    public GameObject GetObj(string objName, Transform parent)
    {
        //结果对象
        GameObject result = null;
        //判断是否有该名字的对象池
        if (pool.ContainsKey(objName))
        {
            //对象池里有对象
            if (pool[objName].Count > 0)
            {
                //获取结果
                result = pool[objName][0];
                //设置父级
                result.transform.SetParent(parent);
                //激活对象
                result.SetActive(true);
                //从池中移除该对象
                pool[objName].Remove(result);
                //返回结果
                return result;
            }
        }
        //如果没有该名字的对象池或者该名字对象池没有对象

        GameObject prefab = null;
        //如果已经加载过该预设体
        if (prefabs.ContainsKey(objName))
        {
            prefab = prefabs[objName];
        }
        else     //如果没有加载过该预设体
        {
            //加载预设体
            prefab = Resources.Load<GameObject>("Prefabs/" + objName);
            //更新字典
            prefabs.Add(objName, prefab);
        }

        //生成
        result = Object.Instantiate(prefab);
        //设置父级
        result.transform.SetParent(parent);
        //改名(去除 Clone)
        result.name = objName;
        result.SetActive(true);
        //返回
        return result;
    }

    /// <summary>
    /// 回收对象到对象池
    /// </summary>
    /// <param name="objName"></param>
    public void RecycleObj(GameObject obj)
    {
        //设置为非激活
        obj.SetActive(false);
        //判断是否有该对象的对象池
        if (pool.ContainsKey(obj.name))
        {
            //放置到该对象池
            pool[obj.name].Add(obj);
        }
        else
        {
            //创建该类型的池子,并将对象放入
            pool.Add(obj.name, new List<GameObject>() { obj });
        }
    }
}

调用时直接单例调用,例如
生成这个预设物

PoolManager.Instance.GetObj("People",transform);

回收

PoolManager.Instance.RecycleObj(gameObject);

注释写的也很清楚。记录下来,以后有用直接看。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔都的放牛娃

如果对你有帮助,已开通打赏服务

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值