Unity 对象池技术
介绍
是什么? | 在开始时初始化若干对象,将它们存到对象池中。需要使用的时候从对象池中取出,使用完后重新放回对象池中。 |
优点 | 可以避免频繁创建和销毁对象带来性能消耗。 |
适用场景 | 如果需要对某种对象进行频繁创建和销毁时,例如应用在发射子弹、多个敌人创建等 |
代码逻辑
Unity中实现思路
1、设定初始化数量,创建List列表作为对象池容器。
2、初始化时通过Instantiate方法根据指定数量实例化一批对象,并存入List容器中。
3、使用时从容器中取出一个可用对象并SetActive(true),取出后从容器中移除。
4、使用完毕后,将对象SetActive(false),并重新放回List容器中。
主要方法
//初始化对象池
private void InitPool()
{}//创建单个对象池中的对象
private GameObject CreatePoolCell()
{}//从对象池中取出可用对象
private GameObject GetObjectFromPool()
{}//将对象放回对象池中
private void BackObjectToPool(GameObject obj)
{}//删除对象池
private void DestroyObjectPool()
{}
示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test : MonoBehaviour
{public GameObject template;public Transform parentRoot;public Transform newRoot;private List<GameObject> objectPool;private int initCount;//对象池初始化的数量void Start(){InitPool();}void Update(){if (Input.GetKeyDown(KeyCode.Space)){var obj = GetObjectFromPool();ResetLocalPos(obj, newRoot);StartCoroutine(Check1(obj));}}IEnumerator Check1(GameObject obj){yield return new WaitForSeconds(5f);BackObjectToPool(obj);}#region 对象池逻辑//初始化对象池private void InitPool(){initCount = 10;objectPool = new List<GameObject>();for (var i = 0; i < initCount; i++){var obj = CreatePoolCell();objectPool.Add(obj);}}//创建单个对象池中的对象private GameObject CreatePoolCell(){var obj = Instantiate(template, parentRoot);obj.SetActive(false);obj.transform.localPosition = Vector3.zero;return obj;}//从对象池中取出可用对象private GameObject GetObjectFromPool(){for (var i = 0; i < objectPool.Count; i++){var obj = objectPool[i];if (!obj.activeInHierarchy){obj.SetActive(true);objectPool.Remove(obj);return obj;}}var newObj = CreatePoolCell();newObj.SetActive(true);return newObj;}//将对象放回对象池中private void BackObjectToPool(GameObject obj){if (objectPool.Contains(obj)){return;}obj.SetActive(false);ResetLocalPos(obj, parentRoot);objectPool.Add(obj);}//删除对象池private void DestroyObjectPool(){foreach (var iconObj in objectPool){DestroyImmediate(iconObj);}objectPool.Clear();}private void ResetLocalPos(GameObject obj,Transform parent){var trans = obj.transform;trans.SetParent(parent);trans.localPosition = Vector3.zero;}#endregion
}
Unity自带对象池
构造函数
//将会在创建新对象的时侯调用
Func<T> createFunc, //会在从池子获取对象的时侯调用
Action<T> actionOnGet = null, //将对象放回池子里的时侯调用
Action<T> actionOnRelease = null, //会在彻底销毁对象的时侯调用
Action<T> actionOnDestroy = null, //安全检查,防止将已经回收过的对象进行再一次的重复回收,默认参数的true即可
bool collectionCheck = true, //池子初始的默认大小,会在初始化时创建一个该容量大小的 stack
//需要根据自己项目的实际需求去权衡一下初始容量的大小。
int defaultCapacity = 10,//主要是防止对象池内存过量增长,限定的对象池内最大可容纳的对象数量,
//如果池子超出了这个大小,接下来的回收对象将不会回到对象池
//而是直接调用它的 actionOnDestroy 回调进行销毁操作。
int maxSize = 10000)
主要属性和方法
接口 | 类型 | 描述 |
CountActive | 属性 | 正在使用(即被激活的)的对象数量 |
CountInactive | 属性 | 可以重用的对象数量 |
CountAll | 属性 | 正在使用的对象和可以重用的对象的总数量 |
Get | 方法 | 从对象池中获取对象 |
Release | 方法 | 将对象放回池子中 |
Clear | 方法 | 清理对象池 |
示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;public class Test : MonoBehaviour
{public GameObject template;public Transform parentRoot;public Transform newRoot;private List<GameObject> objectPool;private int initCount;//对象池初始化的数量private ObjectPool<GameObject> testPool;public bool useObjectPool;void Start(){testPool = new ObjectPool<GameObject>(() =>{//createFunc//将会在创建新对象的时侯调用var obj = Instantiate(template, parentRoot);obj.SetActive(false);obj.transform.localPosition = Vector3.zero;return obj;},(go) =>{// actionOnGet // 会在通过池子获取对象的时侯调用,go.SetActive(true);var trans = go.transform;trans.SetParent(newRoot);trans.localPosition = Random.insideUnitSphere;},(go) =>{// actionOnRelease// 在对象放回池子里的时侯调用,这里我们取消激活需要放回池中的对象go.SetActive(false);var trans = go.transform;trans.SetParent(parentRoot);trans.localPosition = Vector3.zero;},(go) =>{/* actionOnDestroy 会在彻底销毁对象的时侯调用这里直接去destroy它就可以了对象池会在你手动释放对象或者内部空间无法存储你返回的对象的时侯调用这个函数来销毁它们*/Destroy(go); });}void Update(){if (Input.GetKeyDown(KeyCode.Space)){var obj = testPool.Get();StartCoroutine(Check1(obj));}}IEnumerator Check1(GameObject obj){yield return new WaitForSeconds(5f);testPool.Release(obj);}
}
其他类型的对象池
相关文章:

Unity 对象池技术
介绍 是什么? 在开始时初始化若干对象,将它们存到对象池中。需要使用的时候从对象池中取出,使用完后重新放回对象池中。 优点 可以避免频繁创建和销毁对象带来性能消耗。 适用场景 如果需要对某种对象进行频繁创建和销毁时,例…...
算法1-4 凌乱的yyy / 线段覆盖
题目描述 现在各大 oj 上有 n 个比赛,每个比赛的开始、结束的时间点是知道的。 yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。 所以,他想知道他最多能参加几个比赛。 由于 yyy 是蒟蒻,…...

【计网】数据链路层
数据链路层 3.1 数据链路层概述3.2 封装成帧3.3 差错检测3.4 可靠传输3.4.1 可靠传输的概念3.4.2 可靠传输的实现机制 - 停止等待协议3.4.3 可靠传输的实现机制 -回退N帧协议3.4.4 可靠传输的实现机制 -选择重传协议 3.5 点对点协议3.5.1 帧格式3.5.2 透明传输 3.6 媒体接入控制…...

javaweb自用笔记:Vue
Vue 什么是vue vue案例 1、引入vue.js文件 2、定义vue对象 3、定义vue接管的区域el 4、定义数据模型data 5、定义视图div 6、通过标签v-model来绑定数据模型 7、{{message}}直接将数据模型message展示出来 8、由于vue的双向数据绑定,当视图层标签input里的…...
CSS Overflow 属性详解
CSS Overflow 属性详解 在网页设计和开发中,CSS Overflow 属性是一个非常重要的特性,它决定了当内容超出其容器大小时应该如何处理。本文将详细介绍 CSS Overflow 属性的相关知识,包括其语法、作用、常用属性值以及一些实际应用场景。 1. CSS Overflow 属性概述 CSS Over…...

沃丰科技结合DeepSeek大模型技术落地与应用前后效果对比
技术突破:DeepSeek算法创新,显著降低了显存占用和推理成本。仅需少量标注数据即可提升推理能力。这种突破减少了对海量数据的依赖,削弱了数据垄断企业的优势! 商业模式颠覆:DeepSeek选择完全开源模式,迫使…...

突破光学成像局限:全视野光学血管造影技术新进展
全视野光学血管造影(FFOA)作为一种实时、无创的成像技术,能够提取生物血液微循环信息,为深入探究生物组织的功能和病理变化提供关键数据。然而,传统FFOA成像方法受到光学镜头景深(DOF)的限制&am…...
2.反向传播机制简述——大模型开发深度学习理论基础
在深度学习开发中,反向传播机制是训练神经网络不可或缺的一部分。它让模型能够通过不断调整权重,从而将预测误差最小化。本文将从实际开发角度出发,简要介绍反向传播机制的核心概念、基本流程、在现代网络中的扩展,以及如何利用自…...
机器学习校招面经二
快手 机器学习算法 一、AUC(Area Under the ROC Curve)怎么计算?AUC接近1可能的原因是什么? 见【搜广推校招面经四】 AUC 是评估分类模型性能的重要指标,用于衡量模型在不同阈值下区分正负样本的能力。它是 ROC 曲线…...

Spring Boot如何利用Twilio Verify 发送验证码短信?
Twilio提供了一个名为 Twilio Verify 的服务,专门用于处理验证码的发送和验证。这是一个更为简化和安全的解决方案,适合需要用户身份验证的应用。 使用Twilio Verify服务的步骤 以下是如何在Spring Boot中集成Twilio Verify服务的步骤: 1.…...

毕业项目推荐:基于yolov8/yolo11的苹果叶片病害检测识别系统(python+卷积神经网络)
文章目录 概要一、整体资源介绍技术要点功能展示:功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出(xls格式)功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…...

Linux的用户与权限--第二天
认知root用户(超级管理员) root用户用于最大的系统操作权限 普通用户的权限,一般在HOME目录内部不受限制 su与exit命令 su命令: su [-] 用户名 -符号是可选的,表示切换用户后加载环境变量 参数为用户名,…...
【Flink银行反欺诈系统设计方案】1.短时间内多次大额交易场景的flink与cep的实现
【flink应用系列】1.Flink银行反欺诈系统设计方案 1. 经典案例:短时间内多次大额交易1.1 场景描述1.2 风险判定逻辑 2. 使用Flink实现2.1 实现思路2.2 代码实现2.3 使用Flink流处理 3. 使用Flink CEP实现3.1 实现思路3.2 代码实现 4. 总结 1. 经典案例:短…...
HashMap的table数组何时初始化?默认容量和扩容阈值是多少?
HashMap 的 table 数组何时初始化? 答案: table 数组在第一次调用 put() 方法时初始化。 为什么? HashMap 为了节省内存,采用了“懒加载”机制。即使用 new HashMap() 创建对象时,只是计算了参数(如容量、…...

基于CURL命令封装的JAVA通用HTTP工具
文章目录 一、简要概述二、封装过程1. 引入依赖2. 定义脚本执行类 三、单元测试四、其他资源 一、简要概述 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具。它支持文件的上传和下载,是综合传输工具&…...

docker学习笔记(1)从安装docker到使用Portainer部署容器
docker学习笔记第一课 先交代背景 docker宿主机系统:阿里云ubuntu22.04 开发机系统:win11 docker镜像仓库:阿里云,此阿里云与宿主机系统没有关系,是阿里云提供的一个免费的docker仓库 代码托管平台:github&…...

数据集/API 笔记:新加坡PSI(空气污染指数)API
data.gov.sg 数据范围:2016年2月 - 2025年3月 1 获取API方式 curl --request GET \--url https://api-open.data.gov.sg/v2/real-time/api/psi 2 返回数据 API 的数据结构可以分为 3 大部分: 区域元数据(regionMetadata) →…...

计算机网络数据传输探秘:包裹如何在数字世界旅行?
计算机网络数据传输探秘:包裹如何在数字世界旅行? 一、从快递网络看数据传输本质 想象你网购了一件商品: 打包:商家用纸箱包装,贴上地址标签(数据封装)运输:包裹经过网点→分拣中心→运输车(网络节点与链路)签收:快递员核对信息后交付(数据校验与接收)数据的网络…...
笔记:代码随想录算法训练营day36:LeetCode1049. 最后一块石头的重量 II、494. 目标和、474.一和零
学习资料:代码随想录 1049.最后一块石头的重量II 力扣题目链接 思路:如何讲该问题转化为背包问题:还是对半分去碰,对半分去碰碰剩下的就是最小的。然后背包容量就是一半儿,物品重量等于物品价值等于stones[i] 和上…...
Bitmap -> Bitmap安卓设备上的显示和内存
Android 屏幕显示与 Bitmap 内存详解 前言 在 Android 开发中,理解屏幕显示单位和 Bitmap 内存占用是构建高效应用的基础。本文将详细介绍相关概念、计算公式及单位转换,并通过实例分析 Bitmap 在内存中的表现。 一、屏幕显示单位基础 1.1 基本单位及…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
day51 python CBAM注意力
目录 一、CBAM 模块简介 二、CBAM 模块的实现 (一)通道注意力模块 (二)空间注意力模块 (三)CBAM 模块的组合 三、CBAM 模块的特性 四、CBAM 模块在 CNN 中的应用 一、CBAM 模块简介 在之前的探索中…...
【仿生机器人】刀剑神域——爱丽丝苏醒计划,需求文档
仿生机器人"爱丽丝"系统架构设计需求文档 一、硬件基础 已完成头部和颈部硬件搭建 25个舵机驱动表情系统 颈部旋转功能 眼部摄像头(视觉输入) 麦克风阵列(听觉输入) 颈部发声装置(语音输出)…...