对象池介绍

news2024/12/23 17:19:11

对象池介绍

对象池是一种常见的优化技术,用于减少游戏运行时的内存分配和垃圾回收。对象池维护了一组已经创建的对象实例,这些对象可以被多次重复使用,而不需要每次都重新创建和销毁。对象池的主要优点是可以减少内存分配和垃圾回收的次数,从而提高游戏的运行效率。

在 Unity 中,对象池通常使用 ListQueue 来存储对象实例。当需要使用对象时,从对象池中取出一个对象并初始化,当不需要使用对象时,将对象重置并放回对象池中。

对象池方法

在 Unity 中,可以使用以下方法来实现对象池:

创建对象池

List<GameObject> objectPool = new List<GameObject>(); // 使用 List 存储对象池

或者使用 Queue 存储对象池:

Queue<GameObject> objectPool = new Queue<GameObject>(); // 使用 Queue 存储对象池

初始化对象池

在游戏开始时,可以创建一定数量的对象并添加到对象池中,以便在游戏运行时可以快速地使用这些对象。

public GameObject prefab; // 对象池中存储的对象预制体
public int poolSize = 10; // 对象池的大小

private List<GameObject> objectPool = new List<GameObject>();

void Start()
{
    for (int i = 0; i < poolSize; i++)
    {
        GameObject obj = Instantiate(prefab);
        obj.SetActive(false); // 初始状态下,对象不激活
        objectPool.Add(obj);
    }
}

从对象池中取出对象

private GameObject GetObjectFromPool()
{
    GameObject obj;
    if (objectPool.Count > 0)
    {
        obj = objectPool[0];
        objectPool.RemoveAt(0);
    }
    else
    {
        obj = Instantiate(prefab);
    }

    obj.SetActive(true);
    return obj;
}

在上述代码中,如果对象池中有可用的对象,则从对象池中取出一个对象并返回。如果对象池中没有可用的对象,则创建一个新的对象并返回。在返回对象之前,需要将对象设置为激活状态。

将对象放回对象池

private void ReturnObjectToPool(GameObject obj)
{
    obj.SetActive(false);
    objectPool.Add(obj);
}

在上述代码中,将对象设置为不激活状态,并将对象添加回对象池中。

对象池举例子

下面是一些常见的使用对象池的例子:

对象池管理器

可以创建一个对象池管理器,用于管理多个对象池。在对象池管理器中,可以根据对象的类型(例如敌人、子弹、道具等)创建不同的对象池,并提供从对象池中获取和回收对象的方法。

public class ObjectPoolManager : MonoBehaviour
{
    public static ObjectPoolManager instance;

    private Dictionary<string, List<GameObject>> objectPools = new Dictionary<string, List<GameObject>>();

    private void Awake()
    {
        instance = this;
    }

    public GameObject GetObjectFromPool(string poolName)
    {
        if (!objectPools.ContainsKey(poolName))
        {
            objectPools.Add(poolName, new List<GameObject>());
        }

        List<GameObject> pool = objectPools[poolName];
        GameObject obj;

        if (pool.Count > 0)
        {
            obj = pool[0];
            pool.RemoveAt(0);
        }
        else
        {
            obj = Instantiate(prefab);
        }

        obj.SetActive(true);
        return obj;
    }

    public void ReturnObjectToPool(GameObject obj, string poolName)
    {
        obj.SetActive(false);

        if (!objectPools.ContainsKey(poolName))
        {
            objectPools.Add(poolName, new List<GameObject>());
        }

        List<GameObject> pool = objectPools[poolName];
        pool.Add(obj);
    }
}

在上述代码中,我们定义了一个 ObjectPoolManager 类,用于管理多个对象池。在 GetObjectFromPool() 方法中,我们根据对象池的名称从字典中获取相应的对象池。如果对象池不存在,则创建一个新的对象池。然后从对象池中获取一个对象并返回。在 ReturnObjectToPool() 方法中,我们首先将对象设置为不激活状态,然后将对象添加回对象池中。

子弹对象池

可以创建一个子弹对象池,用于管理多个子弹。当需要发射子弹时,从对象池中获取一个子弹并初始化,当子弹碰撞到物体或者到达一定距离时,将子弹重置并放回对象池中。

public class BulletPool : MonoBehaviour
{
    public GameObject bulletPrefab;
    public int poolSize = 10;
    public float lifetime = 2f;

    private List<GameObject> bulletPool = new List<GameObject>();

    void Start()
    {
        for (int i = 0; i < poolSize; i++)
        {
            GameObject bullet = Instantiate(bulletPrefab);
            bullet.SetActive(false);
            bulletPool.Add(bullet);
        }
    }

    public void ShootBullet(Vector3 position, Quaternion rotation, Vector3 direction)
    {
        GameObject bullet = GetBulletFromPool();
        bullet.transform.position = position;
        bullet.transform.rotation = rotation;
        bullet.GetComponent<Bullet>().SetDirection(direction);
        StartCoroutine(ReturnBulletToPool(bullet));
    }

    private GameObject GetBulletFromPool()
    {
        GameObject bullet;
        if (bulletPool.Count > 0)
        {
            bullet = bulletPool[0];
            bulletPool.RemoveAt(0);
        }
        else
        {
            bullet = Instantiate(bulletPrefab);
        }

        bullet.SetActive(true);
        return bullet;
    }

    private IEnumerator ReturnBulletToPool(GameObject bullet)
    {
        yield return new WaitForSeconds(lifetime);
        bullet.SetActive(false);
        bulletPool.Add(bullet);
    }
}

在上述代码中,我们定义了一个 BulletPool 类,用于管理多个子弹。在 Start() 方法中,我们创建了一定数量的子弹并添加到对象池中。在 ShootBullet() 方法中,我们从对象池中获取一个子弹并初始化,然后启动一个协程,等待子弹到达一定距离或者碰撞到物体后,将子弹重置并放回对象池中。在协程 ReturnBulletToPool() 中,我们使用 yield return new WaitForSeconds(lifetime) 等待一定时间后,将子弹设置为不激活状态并添加回对象池中。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744529.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一百零四天学习记录:C++核心:类和对象Ⅶ(五星重要)继承下

继承同名成员处理方式 1、访问子类同名成员&#xff0c;直接访问即可 2、访问父类同名成员&#xff0c;需要加作用域 #include<iostream> using namespace std; class Base { public:Base(){m_A 100;}int m_A;void func(){cout << "Base - func()调用"…

途乐证券-逆市拉升!这一板块超10股涨停

7月12日&#xff0c;A股商场全体走低&#xff0c;个股跌多涨少&#xff0c;厄尔尼诺的冲击波也“搅动”了A股商场&#xff0c;种业、虚拟电厂等概念股纷繁走强。轿车产业链个股继续活泼&#xff0c;超10股涨停。 2023年中期成绩预告仍如火如荼发表中&#xff0c;成绩“预喜”股…

SpringCloud入门实战(十三)Nacos服务注册与发现+配置管理详解

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我&#xff0c;不迷路 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术…

电脑网络最基本的常识简介(合集)

电脑网络最基本的常识简介 什么是HTML? HTML(Hyper Text Mark-up Language )即超文本标记语言&#xff0c;是 WWW 的描述语言&#xff0c;由 Tim Berners-lee提出。设计 HTML 语言的目的是为了能把存放在一台电脑中的文本或图形与另一台电脑中的文本或图形方便地联系在一起&a…

蚁群算法—ACA

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; 目录 一、蚁群算法简介&#x1f353;1.ACA基本思想2.ACA基本原理3.ACA基本步骤 二、算法求解TSP问题&#x1f34e;1.导入数据2.计算城市间相互距离3.初始化参数4.迭代寻找最佳路径5.结果显示End 一、蚁群算法简介&a…

软件 - 配置安装 Photoshop 的 RID 独立运行版本

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/131673004 Adobe Photoshop 是一款专业的图像处理软件,广泛应用于平面设计、摄影、插画、视频制作等领域,可以对各种格式的图片进行编辑、修饰、合成、优化等操作,创…

SpringBoot + Vue 实现酒店客房管理系统

目录 1 问题的提出 5 2系统开发的可行性研究 6 2.1 技术上可行性分析 6 系统现阶段的发展过程中&#xff0c;利用现有人力和物力是完全具备的能力开发出来 6 2.2 经济的可行性分析 6 2.3 操作可行性分析 6 3 需求分析 7 3.1 需求描述 7 3.2 功能需求分析 7 3.3 非功能需求分析…

JDBC学习笔记

目录 一、JDBC 1&#xff1a;为什么要学习JDBC技术 2、JDBC技术概述与理解 3、JDBC使用步骤分析 3.1、注册驱动 3.2 、获取连接 3.3、创建发送sql语句对象 3.4、发送sql语句 3.5、结果集解析 3.6、资源关闭 一、JDBC 1&#xff1a;为什么要学习JDBC技术 1、Java和数…

【雕爷学编程】Arduino动手做(117)---P10V706LED屏模组3

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

亚马逊买家号如何绑定信用卡

要在亚马逊上绑定信用卡作为买家号的支付方式&#xff0c;请按照以下步骤进行操作&#xff1a; 1、登录亚马逊账户&#xff1a;使用您的亚马逊账户用户名和密码登录到亚马逊网站。 2、导航至"我的账户"&#xff1a;在页面右上角&#xff0c;将鼠标悬停在"你好…

安装使用docker-compose

Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排 Docker-Compose将所管理的容器分为三层&#xff0c;分别是工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#xff09;以及容器&#xff08;container&…

【单周期CPU】LoongArch | LA32R | 二选一控制器MUX | 数据通路

前言&#xff1a;本章内容主要是演示在vivado下利用Verilog语言进行单周期简易CPU的设计。一步一步自己实现模型机的设计。本章先介绍单周期简易CPU中数据通路的设计。 &#x1f4bb;环境&#xff1a;一台内存4GB以上&#xff0c;装有64位Windows操作系统和Vivado 2017.4以上版…

华为OD机试真题 Java 实现【矩阵中非1的元素个数】【2023 B卷 200分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明先将[0,0]位置的值变为1。第一次同化&#xff1a;第二次同化&#xff1a; 大家好&#xff0c;我是哪吒。 一、题目描述 存在一个m*n的二维数组&#xff0c;其成员取…

小程序项目时间选择器用法

项目需求是要实现这种形式, 但是相信大家都试了各种插件,都不太合适,uView框架也不能满足自己的需要; 推荐使用:uview-ui-plus 基本上小程序遇到的单选多选 日期 省市区 都可以完美的实现,可以通过插件市场安装使用 但是要实现ui给的原型图 还需要做一下调整 弹性布局给两个选…

Linux查找关键字出现的位置

在Linux中&#xff0c;您可以使用以下命令来查找文件中关键字出现的位置&#xff1a; grep -rnw /path/to/search -e keyword其中&#xff1a; - -r 递归地搜索指定路径下的所有子目录。 - -n 显示匹配行的行号。 - -w 完整匹配单词&#xff0c;而不是部分匹配。 - /path/to/s…

pandas 重复数据处理详解

概要 重复值处理主要涉及两个部分&#xff0c;一个是找出重复值&#xff0c;第二个是删除重复值&#xff0c;也就是根据自己设定的条件进行删除操作。本次来介绍关于重复数据处理的几个常用方法。 定位重复值 对于重复值&#xff0c;我们首先需要查看这些重复值是什么样的形式…

LFU算法的详细介绍与实现

LRU 算法的淘汰策略是 Least Recently Used&#xff0c;也就是每次淘汰那些最久没被使用的数据&#xff1b;而 LFU 算法的淘汰策略是 Least Frequently Used&#xff0c;也就是每次淘汰那些使用次数最少的数据。 LRU 算法的核心数据结构是使用哈希链表 LinkedHashMap&#xff…

spring全家桶(一):如何创建springboot项目

一.如何创建springboot项目 1.通过官网网站创建项目&#xff1a;https://start.spring.io/ 2.eclipse通过插件Spring Tool Suite(sts)创建项目 3.idea默认已经有spring插件 二.程序入口 SpringBootApplication public class HelloApplication {public static void main(Strin…

Linux--获取当前进程的父进程PID(即PPID)

方法一&#xff1a;编程法 #include <sys/types.h>pid_t ppidgetppid(); 方法二&#xff1a;指令法 ps axj | head -1 && ps axj | grep 当前进程PID 注&#xff1a;你会发现&#xff0c;每次查看当前进程PID时&#xff0c;PID都不相同&#xff0c;但是它的P…