简单对象池ObjectPool

注释

在项目上经常会遇到生成很多同样的物体,往往会对性能造成很大的影响,所以可以采用以下的对象池系统来进行简单的操作

对象池系统

这个模块的主代码,主要用于生成对象,销毁对象

    public class ObjectPool : Singleton<ObjectPool>{#region 对象池/// <summary>/// 对象池/// </summary>private Dictionary<string, List<GameObject>> objectPools = new Dictionary<string,                 List<GameObject>>();/// <summary>/// 生成获得一个池子里的物体/// </summary>/// <param name="objectName">物体的名字</param>/// <param name="pos">位置</param>/// <param name="qua">旋转</param>/// <param name="parent">父物体</param>/// <returns>物体</returns>private GameObject SpawnObjectInternal(string objectName, Vector3 pos, Quaternion     qua, Transform parent){//声明需要返回的游戏对象GameObject obj;//如果存在该子池,且子池中有对象if (objectPools.ContainsKey(objectName) && objectPools[objectName].Count > 0){//获取到对象obj = objectPools[objectName][0];//激活对象obj.SetActive(true);//从子池中移除对象objectPools[objectName].RemoveAt(0);}else{//通过名称加载对象预设体GameObject prefab = GetAssets<GameObject>(objectName);//生成对象obj = GameObject.Instantiate(prefab, pos, qua, parent);//改名obj.name = prefab.name;}//返回对象return obj;}/// <summary>/// 生成对象/// </summary>/// <param name="objectName">物体名字</param>/// <param name="pos">位置</param>/// <param name="qua">旋转</param>/// <param name="parent">父物体</param>/// <param name="initAction">事件</param>/// <returns></returns>public GameObject SpawnObject(string objectName, Vector3 pos, Quaternion qua, Transform parent, System.Action<GameObject> initAction){GameObject obj = SpawnObjectInternal(objectName, pos, qua, parent);//初始化obj.GetComponent<PoolObject>().ObjectInit(initAction);return obj;}/// <summary>/// 回收对象/// </summary>/// <param name="obj"></param>public void RecycleObject(GameObject obj){//取消激活obj.SetActive(false);//如果不存在该子池if (!objectPools.ContainsKey(obj.name)){//创造空的子池objectPools.Add(obj.name, new List<GameObject>());}//将对象放入子池objectPools[obj.name].Add(obj);//收尾obj.GetComponent<PoolObject>().ObjectDispose();}#endregion#region 资源管理/// <summary>/// 缓存资源字典/// </summary>private Dictionary<string, Object> assetsCache = new Dictionary<string, Object>();/// <summary>/// 加载资源/// </summary>/// <typeparam name="T"></typeparam>/// <param name="assetPath"></param>/// <returns></returns>public T GetAssets<T>(string assetPath) where T : Object{if (!assetsCache.ContainsKey(assetPath)){//加载资源并存入缓存池assetsCache.Add(assetPath, Resources.Load<T>(assetPath));}return assetsCache[assetPath] as T;}#endregion}

子对象父物体

在池子里的对象,主要在生成对象的时候涉及到初始化工作和收尾工作,还有自动回收,和一些必须实现的接口,主要用于继承作用

/// <summary>/// 池子里的物体/// </summary>public abstract class PoolObject : MonoBehaviour{/// <summary>/// 是否自动回收/// </summary>[Header("是否自动回收")]public bool autoRecycle;/// <summary>/// 回收时间/// </summary>[Header("回收时间")]public float recycleInterval = 2f;protected virtual void OnEnable(){if (autoRecycle){StartCoroutine(DelayRecycle());}}/// <summary>/// 自动回收/// </summary>/// <returns></returns>private IEnumerator DelayRecycle(){//延时yield return new WaitForSeconds(recycleInterval);//回收ObjectPool.Instance().RecycleObject(gameObject);}/// <summary>/// 初始化工作/// </summary>/// <param name="initAction">初始化的时候执行的事件</param>public abstract void ObjectInit(Action<GameObject> initAction);/// <summary>/// 收尾工作/// </summary>public abstract void ObjectDispose();}

子对象

主要用于继承上述代码,如下示例,子弹的脚本继承上述父物体,挂载在子弹预制体上

public class Bullet : PoolObject 
{public override void ObjectInit(Action<GameObject> initAction){Debug.Log("我出来了");initAction?.Invoke(gameObject);}public override void ObjectDispose(){Debug.Log("我收尾了");}
}

实现

我们可以使用简单的测试接口进行测试,生成一个子弹

    private void Update(){if (Input.GetKeyDown(KeyCode.Space)){ObjectPool.Instance().SpawnObject("Bullet", Vector3.zero, Quaternion.identity, null,(GameObject obj) => {obj.transform.position = Vector3.zero;});}}

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

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

相关文章

35、WEB攻防——通用漏洞XSS跨站反射存储DOM盲打劫持

文章目录 XSS产生于前端的漏洞&#xff0c;常产生于&#xff1a; XSS分类&#xff1a; 反射型&#xff08;非持久型&#xff09; 存储型&#xff08;持久型&#xff09;&#xff0c;攻击代码被写入数据库中。常见于&#xff1a;写日志、留言、评论的地方 DOM型 DOM型XSS与…

Kubernetes-Taint (污点)和 Toleration(容忍)

目录 一、Taint&#xff08;污点&#xff09; 1.污点的组成 2.污点的设置、查看和去除 3.污点实验&#xff1a; 二、Toleration&#xff08;容忍&#xff09; 1.容忍设置的方案 2.容忍实验&#xff1a; Taint 和 toleration 相互配合&#xff0c;可以用来避免 pod 被分配…

Windows AD 组策略 通过脚本修改管理员密码:以安全方式

因为本文主要讲的是通过脚本如何以安全方式设置密码&#xff0c;所以关于组策略如何设置请参考这里&#xff1a; WinServer 2019 AD 组策略 启用本地管理员账号&#xff0c;重置密码_ad域命令启用administrator账户-CSDN博客 我们首先要讲一下&#xff0c;以一般方法创建的脚…

2017年认证杯SPSSPRO杯数学建模C题(第二阶段)移动端考研产品的春天真的到来了吗全过程文档及程序

2017年认证杯SPSSPRO杯数学建模 C题 移动端考研产品的春天真的到来了吗 原题再现&#xff1a; 2017 年的全国硕士研究生招生考试共有 201 万人报名参加&#xff0c;比去年增加了 24 万名考生&#xff0c;增加 13.56%。看起来新一轮的考研热潮即将到来&#xff0c;而考研教学和…

【技能---构建github中SSH密钥的流程】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言SSH基于账号口令的安全验证通过SSH连接到服务器打开终端&#xff08;命令行界面&#xff09;使用 SSH 命令连接&#xff1a; 在 Ubuntu 中生成 SSH 密钥并将其添…

用可视化案例讲Rust编程4. 用泛型和特性实现自适配shapefile的读取

本节已经涉及Rust学习曲线上的一个大坑&#xff1a;泛型和特性了&#xff0c;属于语言的深水区&#xff0c;如果初学者&#xff0c;建议看一眼知道有这个功能即可。 如果我们立足于功能实现&#xff0c;那么做到像上一节那样就可以了&#xff0c;从原理上来说&#xff0c;每个…

LeetCode刷题笔记之二叉树(一)

一、二叉树的基础知识 常见的二叉树类型&#xff1a; 满二叉树&#xff08;Full Binary Tree&#xff09;&#xff1a; 只有度为0和度为2的结点&#xff0c;且度为0的结点位于最后一层。完全二叉树&#xff08;Complete Binary Tree&#xff09;&#xff1a; 倒数第二层是满二…

unity36——原神等手游常用的物理bone(弹簧)裙摆,与Cloth(布料)裙摆插件 Magica Cloth 使用教程(一)

目前我们手游开发&#xff0c;经常会遇到头发&#xff0c;双马尾&#xff0c;长裙&#xff0c;飘带等。以前我们都是在三维软件中制作骨骼后&#xff0c;自己手动K针。这样做有一些弊端&#xff0c;时间长&#xff0c;并且K帧的飘带效果没法随着游戏中角色的移动&#xff0c;旋…

【学网攻】 第(8)节 -- 端口安全

文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节 -- 交换机划分Vlan【学网攻】 第(5)节 -- Cisco VTP的使用​​​​​​【学网攻】 第(6)节 -- 三层交换机实现VLAN间路由【学网攻…

【GCC】gpt问答

WebRTC(Web Real-Time Communication)中的RemoteEstimatorProxy是一个重要的组件,它用于在网络传输中处理带宽估计。RemoteEstimatorProxy主要是与谷歌拥塞控制(Google Congestion Control, GCC)算法或接收器估计的最大比特率(Receiver Estimated Maximum Bitrate, REMB)…

前端项目部署发版流程

一、本地代码以全部提交并推送至仓库 二、项目根目录添加&#xff08;Dockerfile、nginx.conf文件&#xff09; 三、npm run build打包生成dist文件&#xff08;项目根目录&#xff09; 四、启动docker(登录状态) 五、执行命令 docker buildx build -t ‘项目的容器集群地…

水库大坝安全监测的技术手段及方法

水库大坝安全监测是指通过仪器观测和巡视检查对水利水电工程主体结构、地基基础、两岸边坡、相关设施以及周围环境所作的测量及观察。水库大坝安全监测是作为水库大坝安全管理的重要组成部分&#xff0c;是掌握水库大坝安全性态的重要手段&#xff0c;是科学调度、安全运行的前…

【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍

Java技术体系方向-JVM虚拟机参数调优原理 内容简介栈上分配与逃逸分析逃逸分析(Escape Analysis)栈上分配基本思想使用场景线程私有对象 虚拟机内存逻辑图JVM内存分配源码&#xff1a;代码总体逻辑 在某些场景使用栈上分配设置JVM运行参数&#xff1a;开启逃逸模式&#xff0c;…

jquery获取select项并移动到另一个select里

用了jquery和bootstrap5。 如下项的左侧可移动到右侧&#xff0c;右侧可移动到左侧。 div代码如下 <div class"input-group mb-3"><span class"input-group-text">可用节点</span><select class"form-select service-type&quo…

uniapp组件库Modal 模态框 的使用方法

目录 #平台差异说明 #基本使用 #传入富文本内容 #异步关闭 #点击遮罩关闭 #控制模态框宽度 #自定义样式 #缩放效果 #API #Props #Event #Method #Slots 弹出模态框&#xff0c;常用于消息提示、消息确认、在当前页面内完成特定的交互操作。 #平台差异说明 AppH5微…

modbus poll测试工具测试modbus tcp与PLC设备连接使用方法

socket默认端口是502&#xff0c;socket连上之后&#xff0c; 按照modbuspoll工具设置的读写参数 生成的RTU命令格式去组装读PLC的设备数据 modbuspoll工具配置&#xff0c;以v9.9.2中文破解版为例&#xff1a; 首先点连接菜单&#xff08;connection&#xff09;建立连接&…

反射式编程中,Mono和Flux两个类的区别

在响应式编程框架如Project Reactor中&#xff0c;Mono和Flux是两个核心类&#xff0c;它们都实现了Reactive Streams规范的Publisher接口&#xff0c;用于处理异步数据流。 1. Mono&#xff1a; Mono代表的是0或1个元素的数据序列。换句话说&#xff0c;它表示的是未来可能产…

for循环延时时间计算

​ 文章目录 前言一、计算方式二、for循环 2.1 for循环里定义变量2.2 codeblock设置C99标准 三、四、总结 前言 之前做led点亮的实验&#xff0c;好像是被delay函数影响了&#xff0c;因为delay参数设置的不对&#xff0c;led没有正常闪烁。现在就想搞明白一些。 一、计算…

Fluent Bit配置与使用——基于版本V2.2.2

Fluent Bit日志采集终端 文档适用版本&#xff1a;V2.2 1、日志文件处理流程 数据源是一个普通文件&#xff0c;其中包含 JSON 内容&#xff0c;使用tail插件记录日志&#xff0c;通过parsers进行格式化匹配&#xff08;图里没写&#xff09;&#xff0c;通过两个筛选器&…

[150] 逆波兰表达式求值 js

题目描述&#xff1a; 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 * * 请你计算该表达式。返回一个表示表达式值的整数。 逆波兰表达式&#xff1a; * * 逆波兰表达式是一种后缀表达式&#xff0c;所谓后缀就是指算符写在后面。 *…