最新Unity DOTS教程之BlobAsset核心机制分析

news2024/9/21 11:11:04

最近DOTS发布了正式的版本, 我们来分享一下DOTS里面BlobAsset机制,方便大家上手学习掌握Unity DOTS开发。

BlobAsset 概叙

DOTS提供了BlobAsset机制来把数据生成高效的二进制数据。BlobAsset的数据是不可变的。BlobAsset只支持非托管类型数据。支持Burst编译器编译出来的类型。同时它只存储非托管类型的数据,这样使得它序列化与反序列化的性能与效率非常的块。BlobAsset也可以被entity种的component使用。

对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。

BlobAsset不支持如:数组, string等其它的托管对象(垃圾回收器可以回收的为托管对象),而且运行的时候不允许改变里面的数据内容。BlobAsset为了更快的加载,他只会包含传值的类型,不能包含对内部的引用与内部指针。BlobAsset除了支持标准的值类型(float, int等)以外它还支持三种特殊的类型: BlobArray, BlobPtr, BlobString。如果BlobAsest包含内部指针,编译器会报错。使用BlobAsset主要注意以下几个方面:

A: 创建一个BlobAsset,你需要先生成一个BlobBuilder,来帮助你处理计算每个数据在内存种的偏移;

总结:使用BlobBuilder来生成BlobAsset,基于BlobAssetReference来高效访问里面的数据。

BlobAsset的创建与使用

创建一个BlobAsset,按照以下步骤来进行处理即可:

BlobBuilder构造出BlobAsset,并把数据存入进去,然后再生成BlobAssetReference<T>来给用户操作数据。参考代码如下:

 struct MarketData
 {
 public float PriceOranges;
 public float PriceApples;
 }
 BlobAssetReference<MarketData> CreateMarketData()
 {
 // Create a new builder that will use temporary memory to construct the blob asset
 var builder = new BlobBuilder(Allocator.Temp);
 // Construct the root object for the blob asset. Notice the use of `ref`.
 ref MarketData marketData = ref builder.ConstructRoot<MarketData>();
 // Now fill the constructed root with the data:
 // Apples compare to Oranges in the universally accepted ratio of 2 : 1 .
 marketData.PriceApples = 2f;
 marketData.PriceOranges = 4f;
 // Now copy the data from the builder into its final place, which will
 // use the persistent allocator
 var result = builder.CreateBlobAssetReference<MarketData>(Allocator.Persistent);
 // Make sure to dispose the builder itself so all internal memory is disposed.
 builder.Dispose();
 return result;
 }
 #endregion

如果你要存数组到BlobAsset,可以使用BlobArray来处理。数组数据内部基于索引的偏移来进行每个元素的定位。将数组存入到BlobAsset的代码如下:

 #region CreateBlobAssetWithArray
 struct Hobby
 {
 public float Excitement;
 public int NumOrangesRequired;
 }
 struct HobbyPool
 {
 public BlobArray<Hobby> Hobbies;
 }
 BlobAssetReference<HobbyPool> CreateHobbyPool()
 {
 var builder = new BlobBuilder(Allocator.Temp);
 ref HobbyPool hobbyPool = ref builder.ConstructRoot<HobbyPool>();
 // Allocate enough room for two hobbies in the pool. Use the returned BlobBuilderArray
 // to fill in the data.
 const int numHobbies = 2;
 BlobBuilderArray<Hobby> arrayBuilder = builder.Allocate(
 ref hobbyPool.Hobbies,
 numHobbies
 );
 // Initialize the hobbies.
 // An exciting hobby that consumes a lot of oranges.
 arrayBuilder[0] = new Hobby
 {
 Excitement = 1,
 NumOrangesRequired = 7
 };
 // A less exciting hobby that conserves oranges.
 arrayBuilder[1] = new Hobby
 {
 Excitement = 0.2f,
 NumOrangesRequired = 2
 };
 var result = builder.CreateBlobAssetReference<HobbyPool>(Allocator.Persistent);
 builder.Dispose();
 return result;
 }
 #endregion

存储string到BlobAsset, 代码如下:

#region CreateBlobAssetWithString
 struct CharacterSetup
 {
 public float Loveliness;
 public BlobString Name;
 }
 BlobAssetReference<CharacterSetup> CreateCharacterSetup(string name)
 {
 var builder = new BlobBuilder(Allocator.Temp);
 ref CharacterSetup character = ref builder.ConstructRoot<CharacterSetup>();
 character.Loveliness = 9001; // it's just a very lovely character
 // Create a new BlobString and set it to the given name.
 builder.AllocateString(ref character.Name, name);
 var result = builder.CreateBlobAssetReference<CharacterSetup>(Allocator.Persistent);
 builder.Dispose();
 return result;
 }
 #endregion

存储BlobPtr数据到BlobAsset,代码如下:

#region CreateBlobAssetWithInternalPointer
 struct FriendList
 {
 public BlobPtr<BlobString> BestFriend;
 public BlobArray<BlobString> Friends;
 }
 BlobAssetReference<FriendList> CreateFriendList()
 {
 var builder = new BlobBuilder(Allocator.Temp);
 ref FriendList friendList = ref builder.ConstructRoot<FriendList>();
 const int numFriends = 3;
 var arrayBuilder = builder.Allocate(ref friendList.Friends, numFriends);
 builder.AllocateString(ref arrayBuilder[0], "Alice");
 builder.AllocateString(ref arrayBuilder[1], "Bob");
 builder.AllocateString(ref arrayBuilder[2], "Joachim");
 // Set the best friend pointer to point to the second array element.
 builder.SetPointer(ref friendList.BestFriend, ref arrayBuilder[2]);
 var result = builder.CreateBlobAssetReference<FriendList>(Allocator.Persistent);
 builder.Dispose();
 return result;
 }
 #endregion

这里的BlobPtr是基于数据的偏移来存储的;

今天的BlobAsset机制,就给大家分享到这里了,更多的DOTS系列,关注我们,持续更新!

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

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

相关文章

计时的vue写法

<el-input type"text" id"timetext" value"00时00分00秒" readonly></el-input> <el-button type"button" click"start()">开始</el-button> <el-button type"button" click"st…

用Visual Studio(VS)开发UNIX/Linux项目

目录 FTP是免不了的 正确设置头文件 组织项目结构 创建何种项目类型 FTP自动上传 大部分具有Windows开发经验的程序员会比较喜欢使用Visual Studio&#xff0c;而大部分Unix/Linux程序员则喜欢使用UltraEdit直接在主机上写代码。 为什么直接在主机上写代码呢&#xff0c;因…

软考系列(系统架构师)- 2015年系统架构师软考案例分析考点

试题一 软件架构&#xff08;质量属性效用树、架构风险、依够点、权衡点&#xff09; 【问题1】&#xff08;12分&#xff09; 在架构评估过程中&#xff0c;质量属性效用树&#xff08;utility tree&#xff09;是对系统质量属性进行识别和优先级排序的重要工具。请给出合适的…

第20章 Netty

20.1 说说IO的交互流程 难度:★ 重点:★ 白话解析 这道题主要是用来帮助理解后面题目的,IO交互主要分为两种:本地IO和网络IO。 1、本地IO:数据在磁盘上,通过系统调用read()方法读取数据到内核空间的缓冲区,然后再读取到 用户空间的缓冲区,这就是IO的交互过程。 2、网…

华为---DHCP中继代理简介及示例配置

DHCP中继代理简介 IP动态获取过程中&#xff0c;客户端&#xff08;DHCP Client&#xff09;总是以广播&#xff08;广播帧及广播IP报文&#xff09;方式来发送DHCPDISCOVER和DHCPREQUEST消息的。如果服务器&#xff08;DHCP Server&#xff09;和 客户端不在同一个二层网络(二…

【100天精通Python】Day71:Python可视化_一文掌握Seaborn库的使用《一》_数据分布可视化,数据关系可视化,示例+代码

目录 1. 数据分布的可视化 1.1 直方图&#xff08;Histograms&#xff09; 1.2 核密度估计图&#xff08;Kernel Density Estimation Plot&#xff09; 1.3 箱线图&#xff08;Box Plot&#xff09; 1.4 小提琴图&#xff08;Violin Plot&#xff09; ​编辑1.5 散点图&am…

蓝桥杯双周赛算法心得——铺地板(质因数)

大家好&#xff0c;我是晴天学长&#xff0c;这是第二周的蓝桥杯的双周赛&#xff0c;题可出的又好又灵活啊&#xff01;真不错&#xff01; 1) .铺地板 2) .算法思路 1.导入java.util包中的Scanner类&#xff0c;以从用户那里读取输入。 2.main方法是程序的入口点。 3.创建一…

单片机仿真设计打包项目

小伙伴们在仿真设计时会遇到各种各样的问题&#xff0c;网上的资料可能不全或者很贵。 这篇也不单纯为了打广告&#xff0c;主要是希望实实在在帮到学单片机的同学&#xff0c;大家不要一有问题就各种找dai zuo&#xff0c;做的好不好是一回事儿&#xff0c;关键是它费&#x…

成都无人机测绘公司 无人机测绘服务 无人机航测作业

无人机测绘是传统航空摄影测量方式的重要补充方式&#xff0c;它具有灵活、高效、适用范围广、生产周期短等优势&#xff0c;在小区域和飞行困难地区获取高分辨率图像具有明显的优势。目前&#xff0c;无人机测绘主要应用于土地监管、灾害应急处理、城市规划管理等方面。那么&a…

el-date-picker如何回显

后端传输过来起止时间&#xff0c;需要回显在 el-date-picker中 未修改前的代码&#xff1a; 问题整改&#xff1a;需要将时间转换为Date类型 修改后的代码 setTime(date){if (date!null){this.value.push(new Date(date.startTime))this.value.push(new Date(date.endTime))c…

一个Entity Framework Core的性能优化案例

概要 本文提供一个EF Core的优化案例&#xff0c;主要介绍一些EF Core常用的优化方法&#xff0c;以及在优化过程中&#xff0c;出现性能反复的时候的解决方法&#xff0c;并澄清一些对优化概念的误解&#xff0c;例如AsNoTracking并不包治百病。 本文使用的是Dotnet 6.0和EF…

前端工作流异常时候 yarn检查异常信息

HDSF中执行异常的原因查询&#xff0c;查看yarn的报错

Kafka - 消息队列的两种模式

文章目录 消息队列的两种模式点对点模式&#xff08;Point-to-Point&#xff0c;P2P&#xff09;发布/订阅模式&#xff08;Publish/Subscribe&#xff0c;Pub/Sub&#xff09; 小结 消息队列的两种模式 消息队列确实可以根据消息传递的模式分为 点对点模式发布/订阅模式 这两…

【Linux】tail命令使用

tail 命令可用于查看文件的内容&#xff0c;有一个常用的参数 -f 常用于查阅正在改变的日志文件。 语法 tail [参数] [文件] tail命令 -Linux手册页 著者 由保罗鲁宾、大卫麦肯齐、伊恩兰斯泰勒和吉姆梅耶林撰写。 命令选项及作用 执行令 tail --help 执行命令结果 参…

数据传输如何做才安全:保障隐私的5大秘诀!

在当今数字时代&#xff0c;数据传输安全和隐私保护变得越来越重要。随着网络攻击和数据泄露事件的增加&#xff0c;保护数据传输安全和隐私已经成为当务之急。以下是保障隐私的五大秘诀&#xff1a; 使用加密技术&#xff1a;加密技术是保护数据传输安全的最常用方法。通过使用…

【设计模式】第1节:UML类图

本系列文章主要参考自B站用户以诺爱编程的《设计模式》系列视频&#xff0c;以及王争的《设计模式之美》系列文章。 本文参考自30分钟学会UML类图。 UML图有很多种&#xff0c;一般只要掌握类图、用例图、时序图就可以完成大部分工作。本文算是学习设计模式的一道前菜&#x…

数字人解决方案——解决ER-NeRF/RAD-NeRF人像分割的问题

一、训练数据人像分割 训练ER-NeRF或者RAD-NeRF时&#xff0c;在数据处理时&#xff0c;其中有一步是要把人像分割出来&#xff0c;而且人像要分成三块&#xff0c;人的头部&#xff0c;人的有脖子&#xff0c;人的身体部分&#xff0c;效果如下&#xff1a; 从上面的分割的结…

【设计模式】第2节:七大设计原则

一、七大设计原则 七大原则提出的目的是降低对象之间的耦合度&#xff0c;提高程序的可复用性、可扩展性和可维护性。 1.单一职责原则 Single Responsibility Principle&#xff0c;SRP原则&#xff1a;一个类只负责一个功能领域中的相应职责。或者可以定义为&#xff1a;就一…

安防视频监控平台EasyNVR平台如何在角色表格中添加信息

TSINGSEE青犀视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入&#xff0c;并能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。在智慧安防等视频监控场景中&#xff0c;EasyNVR可提供视频实时监控直播、云端…

Linux | 进程

目录 前言 一、什么是进程 1、Window下的进程 2、深刻理解进程 3、见一见Linux下的进程 二、进程的创建 1、初始fork 2、fork的返回值 3、深刻理解fork函数 4、遗留问题 三、进程状态 1、操作系统中的进程状态 2、Linux中的进程状态 3、状态演示 &#xff08…