IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> unity对象池的制作(笔记) -> 正文阅读

[游戏开发]unity对象池的制作(笔记)

教程链接11:00

一、大致思路:

1.创建一个字典保存所有对象池,并将对象池与对象池名称联系起来。

2.单例模式来储存数据。

3.一个方法调用对象池的对象,一个方法将弃用的对象放回对象池。

4.管理实例化的对象,让其在运行窗口上看起来不杂乱。

5.对象池的使用。

二、观前提示:

注意代码中的数据与游戏物体的关系

这里我们希望在窗口中通过“ObjectPool”来作为不同对象池的父物体。将每个对象池物体的名字都设置为相应预制体的名字+"Pool",并作为相应对象的父物体。效果如下。

实际对象池的数值储存情况如下

三、代码

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

public class ObjectPool 
{
    private static ObjectPool instance;//储存当前实例

    //通过字典可以快速的根据名称查找到相应对象池,使用队列可以方便的删减元素(无需指定元素)
    private Dictionary<string, Queue<GameObject>> objectPool = new Dictionary<string, Queue<GameObject>>();
    


    private GameObject pool;//作为所有对象池的父物体,便于管理。

    //单例模式
    public static ObjectPool Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new ObjectPool();
            }
            
                return instance;
        }
    }

先初步写一下调用方法

public GameObject GetObject(GameObject prefab)
    {
        GameObject _object;//稍后我们将所取出的对象绑定在该物体上返回

        /*现在已经知道了所需的游戏对象,我们要从对象池中获得这个对象。
   现在分为三种情况:
        ①相应对象池中有剩余对象
        ②相应对象池中没有剩余对象
        ③没有相应对象池
   对应的处理办法:
        ①取出相应对象池的对象,激活,并返回
        ②实例化一个对象,并将其放入对象池中,执行①
        ③实例化一个对象,(创建新的对象池)并将其放入对象池中,执行①
        使用if区分不同的处理方法,将共同的处理方法放在外面
        这里在PushObject中创建新的对象池,可能是为了精简下代码(也有可能有其他理由,望指出)
       */
       
        if (objectPool.ContainsKey(prefab.name)==false||objectPool[prefab.name].Count == 0)//③
        {
            _object = GameObject.Instantiate(prefab);//实例化一个所需对象

            //稍后向此处插入代码设置新对象的父子关系,维持unity中游戏对象的整洁性


            PushObject(_object);//将对象放入对象池中
        }
        
        _object = objectPool[prefab.name].Dequeue();//取出相应对象并激活
        _object.SetActive(true);
        return _object;
        
    }

再编写"PushObject"

  /*我们得到了需要放入对象池的对象,
现存在两种情况
    ①存在对应对象池
    ②不存在对应对象池
 对应的处理办法
    ①将对象放入相应对象池中并使其失效
    ②向字典中添加新的对象池元素,执行①*/
    public void PushObject(GameObject prefab)
    {
        string _name = prefab.name.Replace("(Clone)", string.Empty);//实例化的物体后都会带有“(Clone)”
        if (objectPool.ContainsKey(_name) == false)//②
        {
            objectPool.Add(_name, new Queue<GameObject>());//向字典中添加新的对象池元素
        }
       //将对象放入相应对象池中并使其失效
        objectPool[_name].Enqueue(prefab);
        prefab.SetActive(false);
       
    }

现在一个基本的对象池就已经成型了,但我们还需要让编辑窗口看起来没那么杂乱,所以要分配不同对象之间的关系。因为物体实例化发生在GetObject方法中,所以我选择在这个方法中进行分配,分配位置上面已经标明。

 if (pool == null)
            {
                pool = new GameObject("ObjectPool");//创建一个物体管理所有对象池
            }
            //寻找并绑定相应对象池物体,如果对象物体不存在则创建一个对象池物体
            GameObject childPool = GameObject.Find(prefab.name + "pool");
            if (!childPool)
            {
                childPool = new GameObject(prefab.name + "pool");
            }
            //设置好他们的关系
            childPool.transform.SetParent(pool.transform);
            _object.transform.SetParent(childPool.transform);

这是全部的代码,可以再阅读试试是否已经理解

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

public class ObjectPool 
{
   
    private Dictionary<string, Queue<GameObject>> objectPool = new Dictionary<string, Queue<GameObject>>();
    private GameObject pool;

    private static ObjectPool instance;
    public static ObjectPool Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new ObjectPool();
            }
            
                return instance;
        }
    }
    
    public GameObject GetObject(GameObject prefab)
    {
        GameObject _object;
        if (!objectPool.ContainsKey(prefab.name)|| objectPool[prefab.name].Count == 0)//③
        {
            _object = GameObject.Instantiate(prefab);


            if (pool == null)
            {
                pool = new GameObject("ObjectPool");
            }
            GameObject childPool = GameObject.Find(prefab.name + "pool");
            if (!childPool)
            {
                childPool = new GameObject(prefab.name + "pool");
            }
            childPool.transform.SetParent(pool.transform);
            _object.transform.SetParent(childPool.transform);

            PushObject(_object);
           
        }
        _object = objectPool[prefab.name].Dequeue();
        _object.SetActive(true);
        return _object;
    }

    public void PushObject(GameObject prefab)
    {
        string _name = prefab.name.Replace("(Clone)", string.Empty);
        if (objectPool.ContainsKey(_name) == false)
        {
            objectPool.Add(_name, new Queue<GameObject>());
        }
        objectPool[_name].Enqueue(prefab);
        prefab.SetActive(false);

    }

}

最后,我们需要调用该类中的方法,使用单例调用

ObjectPool.Instance.GetObject(bulletPrefab);

四、感想:

好爽!!!!!!!!!!!!

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:32:18  更:2021-08-04 11:33:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 17:05:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码