欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

U3D框架(三):对象池

程序员文章站 2022-07-08 10:09:43
对象池原理:将子弹之类的物体回收关闭,再次调用的时候打开,这样可以防止数据被频繁的创建和删除。如果只是单个对象池,我们用一个list即可实现。不过为了方便,项目中通常会把这部分单独提炼出来。总游戏池的代码类似如下:using System.Collections;using System.Collections.Generic;using UnityEngine;public class ObjectPool{ public static readonly ObjectP...

对象池原理:将子弹之类的物体回收关闭,再次调用的时候打开,这样可以防止数据被频繁的创建和删除。

如果只是单个对象池,我们用一个list即可实现。

不过为了方便,项目中通常会把这部分单独提炼出来。

总游戏池的代码类似如下:

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

public class ObjectPool
{
    public static readonly ObjectPool Inst = Singleton<ObjectPool>.Inst;

    /// <summary>
    /// 对象池,字典中与key值对应的是数组(arraylist)(例:key为手枪子弹  对应arraylist[手枪子弹,手枪子弹,手枪子弹。。。。。。 ])。
    /// </summary>
    private Dictionary<string, List<GameObject>> Pool;

    /// <summary>
    /// 从对象池中获取对象
    /// </summary>
    /// <param name="_objName"></param>
    /// <returns></returns>
    public GameObject GetObj(string _objAffiliation, string _objName)
    {
        GameObject _result = null;

        //判断是否有该名字的对象池      //对象池中有对象
        if (Pool.ContainsKey(_objName) && Pool[_objName].Count > 0)
        {
            //Debug.Log("调用对象池:" + _objName);
            //获取这个对象池中的第一个对象
            _result = Pool[_objName][0];

            if(_result==null) Debug.LogError(Pool[_objName].Count+ _objName);
            //激活对象
            _result.SetActive(true);
            //从对象池中移除对象
            Pool[_objName].Remove(_result);

            //返回结果
            return _result;
        }
        //如果没有该名字的对象池或者该名字对象池没有对象
        //Debug.Log(_objAffiliation + "  " + _objName);
        GameObject _prefab = /*Main.UploadResource.transform.Find("" + _objAffiliation + "/" + _objName).gameObject;*/
            null;

        //实例化物体
        _result = UnityEngine.Object.Instantiate(_prefab);
   
        //改名 去除Clone
        _result.name = _objName;
        _result.SetActive(true);
        return _result;
    }
    /// <summary>
    /// 回收对象到对象池
    /// </summary>
    public void RecycleObj(GameObject _obj, bool _isMap = false)
    {
        if (_obj == null || !_obj.activeInHierarchy) return;
        _obj.SetActive(false);

        //如果有该对象的对象池,直接放在池子中
        if (Pool.ContainsKey(_obj.name))
        {
            Pool[_obj.name].Add(_obj);
        }
        else//如果没有该对象的对象池,创建一个该类型的池子,并将对象放入
        {
            //Debug.Log("新建一个对象池:" + Obj.name);
            Pool.Add(_obj.name, new List<GameObject>() { _obj });
        }

    }
    /// <summary>
    /// 移除所有的数组
    /// </summary>
    public void RemoveAll()
    {
        Pool.Clear();
    }
}

 

单例对象池类似如下:

/// <summary>
/// 简易的池
/// </summary>
public class SimplePool
{
    private List<GameObject> objPool;//存储物体的池

    private string poolName;

    private string path;
    //创建池
    public void CreatPool(string _name,string _path)
    {
        objPool = new List<GameObject>();
        poolName = _name;
        path = _path;
    }

    //创建物体
    public GameObject CreatObj()
    {
        GameObject obj = null;
              
        if (objPool.Count > 0)
        {
            obj = objPool[0];
            objPool.Remove(obj);
        }
        else
        {
            //Debug.Log(path + "/" + poolName);
            obj = UnityEngine.Object.Instantiate( Resources.Load(path+ "/" + poolName) as GameObject);
            //Debug.Log(obj);
        }
        obj.name = poolName;
        obj.transform.position = -100 * Vector3.one;
        obj.SetActive(true);        
        //Debug.LogError("剩余长度"+objPool.Count);
        return obj;    
    }

    //回收物体
    public void RecycleObj(GameObject obj)
    {
        if (obj==null || obj.activeSelf == false) return;
        obj.SetActive(false);
        objPool.Add(obj);
        //Debug.LogError("新增长度" + objPool.Count);
    }

    //清除池
    public void ClearPool()
    {
        for (var idx = objPool.Count - 1; idx >= 0; idx--)
        {
            GameObject _obj = objPool[idx];
            objPool.Remove(_obj);
            GameObject.Destroy(_obj);
        }
        objPool.Clear();
    }
}

需要注意的是,在Resources首次加载物体的时候,会有短暂的卡顿,所以最好对于占用内存比较大的物体,使用异步加载。

本文地址:https://blog.csdn.net/Tel17610887670/article/details/107892624

相关标签: 框架