Unity DOTS系列之Filter Baking Output与Prefab In Baking核心分析
最近DOTS发布了正式的版本, 我们来分享一下DOTS里面Baking核心机制,方便大家上手学习掌握Unity DOTS开发。今天给大家分享的Baking机制中的Filter Baking Output与Prefab In Baking。
对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。
Filter Baking Output 机制
在默认情况下,Baking会为每个GameObject生成的Entity与Component, 这些entity都会被创建到Conversion World里面。然后在创作的时候不是所有的GameObject都需要被转换成Entity。例如: 在一个样条曲线上,一个控制点在创作的时候被用到了,但是bake成ecs数据后可能就再也没有用了,所以不需要把这个控制点Bake成entity。
为了不把这个GameObject Bake产生的Entity输出到World并保存到entity scene里面,我们可以给这个Entity添加一个BakingOnlyEntity tag Component。当你添加了这个tag component后,Baking系统就不会把你这个entity存储到entity scene里面,也不会把这个entity生成到运行的main World里面。我们可以直接在Baker函数里面添给entity 添加一个BakingOnlyEntity的组件数据,也可以在Authoring GameObject里面添加一个 BakingOnlyEntityAuthoring的组件,这两种方式都可以达到同样的效果没有区别。
你也可以给组件添加注解[BakingType],[TemporaryBakingType] attributes过滤掉掉组件component,让它不输出到entity中。
[TemporaryBakingType]:被这个attributes注记的Component会在Baking Output的时候不会输出到entity。这个Component只会存活在Baker过程中,Baker结束以后就会销毁。
我们有时候需要在Baking System里面批量处理一些组件数据,处理完后这些组件就没有用了。例如,baker 把一个bounding box 转换成了ecs component 数据,接下来我们定义了一个Baking System批量处理所有的entity,来计算entity的凸包。计算完成后原来的bounding box组件就可以删除了,这种情况下就可以使用上面的Filter Component Bake output机制。
Prefab In Baking机制
生成entity prefab到entity scene以后,我们就可以像使用普通的Prefab创建GameObject一样来创建entity到世界。但是使用enity prefab之前一定要确保它已经被Baker到了entity scene。当预制体实例化到Authoring Scene中的时候,Baking把它当作普通的GameObject来进行转换,不会把它当作预制体。
生成一个entity prefab你需要注册一个Baker,在Bake函数里面添加一个依赖关系,让这个依赖于Authoring GameObject Prefab。然后Prefab将会被bake出来。我们搞一个组件保存了entity prefab的一个引用,那么unity就会把这个entity prefab 序列化到subscene中。当需要使用这个entity prefab的时候就能获取到。代码如下:
public struct EntityPrefabComponent : IComponentData{public Entity Value;}public class GetPrefabAuthoring : MonoBehaviour{public GameObject Prefab;}public class GetPrefabBaker : Baker<GetPrefabAuthoring>{public override void Bake(GetPrefabAuthoring authoring){// Register the Prefab in the Bakervar entityPrefab = GetEntity(authoring.Prefab, TransformUsageFlags.Dynamic);// Add the Entity reference to a component for instantiation latervar entity = GetEntity(TransformUsageFlags.Dynamic);AddComponent(entity, new EntityPrefabComponent() {Value = entityPrefab});}}#endregion
在Baking的时候,当我们需要引用一个entity prefab, 可以使用EntityPrefabReference。这个会把它序列化到entity scene文件里面去。运行的时候直接load进来,就可以使用了。这样可以防止多个subscene不用重复拷贝生成同一个Prefab。
#region InstantiateLoadedPrefabspublic partial struct InstantiatePrefabReferenceSystem : ISystem{public void OnStartRunning(ref SystemState state){// Add the RequestEntityPrefabLoaded component to the Entities that have an// EntityPrefabReference but not yet have the PrefabLoadResult// (the PrefabLoadResult is added when the prefab is loaded)// Note: it might take a few frames for the prefab to be loadedvar query = SystemAPI.QueryBuilder().WithAll<EntityPrefabComponent>().WithNone<PrefabLoadResult>().Build();state.EntityManager.AddComponent<RequestEntityPrefabLoaded>(query);}public void OnUpdate(ref SystemState state){var ecb = new EntityCommandBuffer(Allocator.Temp);// For the Entities that have a PrefabLoadResult component (Unity has loaded// the prefabs) get the loaded prefab from PrefabLoadResult and instantiate itforeach (var (prefab, entity) inSystemAPI.Query<RefRO<PrefabLoadResult>>().WithEntityAccess()){var instance = ecb.Instantiate(prefab.ValueRO.PrefabRoot);// Remove both RequestEntityPrefabLoaded and PrefabLoadResult to prevent// the prefab being loaded and instantiated multiple times, respectivelyecb.RemoveComponent<RequestEntityPrefabLoaded>(entity);ecb.RemoveComponent<PrefabLoadResult>(entity);}ecb.Playback(state.EntityManager);ecb.Dispose();}}#endregion
实例化entity prefab可以使用EntityManager与entity command buffer。
#region InstantiateEmbeddedPrefabspublic partial struct InstantiatePrefabSystem : ISystem{public void OnUpdate(ref SystemState state){var ecb = new EntityCommandBuffer(Allocator.Temp);// Get all Entities that have the component with the Entity referenceforeach (var prefab inSystemAPI.Query<RefRO<EntityPrefabComponent>>()){// Instantiate the prefab Entityvar instance = ecb.Instantiate(prefab.ValueRO.Value);// Note: the returned instance is only relevant when used in the ECB// as the entity is not created in the EntityManager until ECB.Playbackecb.AddComponent<ComponentA>(instance);}ecb.Playback(state.EntityManager);ecb.Dispose();}}#endregion
实例化EntityPrefabReference,可以使用如下代码:#region InstantiateLoadedPrefabspublic partial struct InstantiatePrefabReferenceSystem : ISystem{public void OnStartRunning(ref SystemState state){// Add the RequestEntityPrefabLoaded component to the Entities that have an// EntityPrefabReference but not yet have the PrefabLoadResult// (the PrefabLoadResult is added when the prefab is loaded)// Note: it might take a few frames for the prefab to be loadedvar query = SystemAPI.QueryBuilder().WithAll<EntityPrefabComponent>().WithNone<PrefabLoadResult>().Build();state.EntityManager.AddComponent<RequestEntityPrefabLoaded>(query);}public void OnUpdate(ref SystemState state){var ecb = new EntityCommandBuffer(Allocator.Temp);// For the Entities that have a PrefabLoadResult component (Unity has loaded// the prefabs) get the loaded prefab from PrefabLoadResult and instantiate itforeach (var (prefab, entity) inSystemAPI.Query<RefRO<PrefabLoadResult>>().WithEntityAccess()){var instance = ecb.Instantiate(prefab.ValueRO.PrefabRoot);// Remove both RequestEntityPrefabLoaded and PrefabLoadResult to prevent// the prefab being loaded and instantiated multiple times, respectivelyecb.RemoveComponent<RequestEntityPrefabLoaded>(entity);ecb.RemoveComponent<PrefabLoadResult>(entity);}ecb.Playback(state.EntityManager);ecb.Dispose();}}#endregion
在实例化EntityPrefabReference之前,Unity必须要先加载对应的entity prefab,然后才能使用它,添加RequestEntityPrefabLoaded组件能确保entity prefab被加载。Unity会PrefabLoadResult加载到带有RequestEntityPrefabLoaded同一个entity上。
预制体也是entity,也可以被查询到,如果需要把一个预制体被查询到,可以在查询条件上添加IncludePrefab。
#region PrefabsInQueries// This query will return all baked entities, including the prefab entitiesvar prefabQuery = SystemAPI.QueryBuilder().WithAll<BakedEntity>().WithOptions(EntityQueryOptions.IncludePrefab).Build();
#endregion
使用EntityManager与entity command buffer也可以销毁一个预制体节点,代码如下:#region DestroyPrefabsvar ecb = new EntityCommandBuffer(Allocator.Temp);foreach (var (component, entity) inSystemAPI.Query<RefRO<RotationSpeed>>().WithEntityAccess()){if (component.ValueRO.RadiansPerSecond <= 0){ecb.DestroyEntity(entity);}}ecb.Playback(state.EntityManager);ecb.Dispose();#endregion
今天的Baking 系列就分享到这里了,关注我学习更多的最新Unity DOTS开发技巧。
相关文章:

Unity DOTS系列之Filter Baking Output与Prefab In Baking核心分析
最近DOTS发布了正式的版本, 我们来分享一下DOTS里面Baking核心机制,方便大家上手学习掌握Unity DOTS开发。今天给大家分享的Baking机制中的Filter Baking Output与Prefab In Baking。 对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础…...
Matlab读写操作
随机生成一个3*3矩阵,对矩阵进行按列升序排列 >> Arand(3,3); >> [B, ~] sort(A, 2); >> B B 0.4898 0.6797 0.70940.4456 0.6551 0.75470.1626 0.2760 0.6463在不同数值类型下显示π的值 1、默认数值类型 >> p_defa…...

Android 开发技巧:音乐播放器的后台处理【Service、Handler、MediaPlayer】
给定部分完成的MusicPlayer项目,实现其中未完成的service部分: 1、创建MusicService类,通过service组件实现后台播放音乐的功能; 2、在MainActivity中通过ServiceConnection连接MusicService,实现对音乐播放的控制&…...

使用Windows平台的Hyper-V虚拟机安装CentOS7的详细过程
Hyper-V虚拟机安装CentOS7 前言常见Linux系统CentOSUbuntuDebianKaliFedoraArch LinuxMintManjaroopenSUSE Hyper-V开启Hyper-V打开Hyper-V Hyper-V的使用新建虚拟机开始安装分区配置开始安装 修改yum源为阿里源 前言 作为一名开发者,就服务器而言,接触最…...

某马机房预约系统 C++项目(二) 完结
8.4、查看机房 8.4.1、添加机房信息 根据案例,我们还是先在computerRoom.txt中直接添加点数据 //几机房 机器数量 1 20 2 50 3 1008.4.2、机房类创建 同样我们在头文件下新建一个computerRoom.h文件 添加如下代码: #pragma once #include<i…...

npm 安装到指定文件夹
创建一个文件夹,用vscode或者cmd打开, 执行 npm install --prefix ./ 路径 包名, npm install --prefix ./ 包名 , 就会将包安装在当前文件夹, 例如: npm install --prefix ./ -g oppo-minigame…...

自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例
自建的离散傅里叶变换matlab程序实现及其与matlab自带函数比较举例 在matlab中有自带的离散傅里叶变换程序,即fft程序,但该程序是封装的,无法看到源码。为了比较清楚的了解matlab自带的实现过程,本文通过自建程序实现matlab程序&…...

Vue图片路径问题(动态引入)
vue项目中我们经常会遇到动态路径的图片无法显示的问题,以下是静态路径和动态路径的常见使用方法。 1.静态路径 在日常的开发中,图片的静态路径通过相对路径和绝对路径的方式引入。 相对路径:以.开头的,例如./、../之类的。就是…...

项目部署Linux步骤
1、最小化安装centos7-环境准备 安装epel-release 安装epel-release,因为有些rpm包在官方库中找不到。前提是保证可以联网 yum install -y epel-release 修改IP net-tools net-tool:工具包集合,包含ifconfig等命令 yum install -y net-…...

UG\NX二次开发 在资源栏(左侧面板)中添加按钮
文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 感谢粉丝订阅 感谢 apolloryd 订阅本专栏,非常感谢。 简介 UG\NX二次开发 在资源栏(左侧面板)中添加按钮,下面提供了帮助说明,在 UGOPEN 文件夹下有示例。 C++语言在UG二次…...

Proteus仿真--量程自动切换数字电压表(仿真+程序)
本文主要介绍基于51单片机的量程自动切换数字电压表Proteus仿真设计(完整仿真源文件及代码见文末链接) 简介 硬件电路主要分为单片机主控模块、AD转换模块、量程选择模块以及数码管显示模块 (1)单片机主控模块:单片…...

如何使用ArcGIS Pro制作一张地形图
01数据来源 本教程所使用的数据是从水经微图中下载的DEM数据,除了DEM数据,常见的GIS数据都可以从水经微图中下载,你可以通过关注“水经注GIS”,然后在后台回复“微图”即可获取软件下载地址,当然也可以直接在水经注…...
人工智能三要数之算法Transformer
1. 人工智能三要数之算法Transformer 人工智能的三个要素是算法、数据和计算资源。Transformer 模型作为一种机器学习算法,可以应用于人工智能系统中的数据处理和建模任务。 算法: Transformer 是一种基于自注意力机制的神经网络模型,用于处理序列数据的…...
Java ThreadPoolExecutor 线程池
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.ArrayBlockingQueue;public class ThreadPoolExample {public static void main(String[] args) {// 创建线程池对象ThreadPoolExecutor threadPool new…...

网络协议--IP选路
9.1 引言 选路是IP最重要的功能之一。图9-1是IP层处理过程的简单流程。需要进行选路的数据报可以由本地主机产生,也可以由其他主机产生。在后一种情况下,主机必须配置成一个路由器,否则通过网络接口接收到的数据报,如果目的地址不…...

使用udevil自动挂载U盘或者USB移动硬盘
最近在折腾用树莓派(实际上是平替香橙派orangepi zero3)搭建共享文件服务器,有一个问题很重要,如何在系统启动时自动挂载USB移动硬盘。 1 使用/etc/fstab 最开始尝试了用/etc/fstab文件下增加:"/dev/sda1 /home/orangepi/s…...

学习笔记二十二:K8s控制器Replicaset
K8s控制器Replicaset Replicaset控制器:概念、原理解读Replicaset概述Replicaset工作原理:如何管理PodReplicaset控制器三个组成部分 Replicaset资源清单文件编写技巧Replicaset使用案例:部署Guestbook留言板编写一个ReplicaSet资源清单资源清…...
2023-10-25 精神分析-领悟新技术的错误做法-持续数年的错误做法-记录与分析
摘要: 过去数年对于领悟技术, 采取的做法不能说是对达到目的毫无裨益,但是对突破技术和将技术融为自身这个目的来说, 没有达到。 而且随着时间的流逝, 过去已经熟悉的技术, 竟然会被忘掉!就像是没有涉猎过一样! 根本原因出在对技术的领悟的…...
Arrays 中的 asList()方法
public static <T> List<T> asList( T . . . a ){ return new ArrayList<>(a); } 返回由指定数组支持的固定大小的 list集合。对数组所做的更改将在返回的 l…...

基于自动化工具autox.js的抢票(猫眼)
1.看到朋友圈抢周杰伦、林俊杰演唱会票贼难信息,特研究了一段时间,用autox.js写了自动化抢票脚本,购票页面自动点击下单(仅限安卓手机)。 2.脚本运行图 3.前期准备工作 (1)autox.js社区官网:AutoX.js (2)b站上学习资料:10分钟学会AutoX.js hello world_哔哩哔哩_bi…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...

云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...