当前位置: 首页 > news >正文

Unity DOTS从入门到精通之EntityCommandBufferSystem

文章目录

    • 前言
    • 安装 DOTS 包
    • ECB
    • ECB可以执行的指令
    • 示例:

前言

DOTS(面向数据的技术堆栈)是一套由 Unity 提供支持的技术,用于提供高性能游戏开发解决方案,特别适合需要处理大量数据的游戏,例如大型开放世界游戏。
本文讲解了如何使用“ ECB ”来执行Job处理过程中无法执行的命令,例如“创建实体”。

  • Unity 2022.3.52f1
  • Entities 1.3.10

安装 DOTS 包

要安装 DOTS 包,请按照以下步骤操作:

(1)从菜单“窗口 → 包管理器”打开包管理器。
(2)搜索“ Entities” 并安装 Entities和Entities Graphics。
(3)搜索“ Universal RP” 并安装 Universal RP,并设置Graphics/Scriptable Render Pipeline Settings。

这会添加“实体”作为依赖项,并递归添加它所依赖的关联包( Burst、Collections、Jobs、Mathematics等)。

在这里插入图片描述

ECB

“ ECB ” (Entity Command Buffer) 是一个缓冲区,在 Unity DOTS 中用于管理和执行 EntityCommandBuffer 命令队列的重要系统。它确保了跨线程和跨帧操作的安全性
默认提供了以下几种 EntityCommandBufferSystem 实现:
BeginInitializationEntityCommandBufferSystem
EndInitializationEntityCommandBufferSystem
BeginSimulationEntityCommandBufferSystem
EndSimulationEntityCommandBufferSystem
BeginPresentationEntityCommandBufferSystem
EndPresentationEntityCommandBufferSystem
FixedStepSimulationEntityCommandBufferSystem
这些系统的名称中包含了它们所属的阶段(Initialization、Simulation、Presentation)以及它们在这些阶段中的执行时机(Begin 和 End)。
在这里插入图片描述

ECB可以执行的指令

ECB 可以执行的命令在 EntityCommandBuffer 方法中定义。
・AddBuffer(Entity):添加一个缓冲区。
・AddComponent(Entity, T):添加一个组件。
・AddComponent(EntityQuery,ComponentType):添加一个组件。
・AddSharedComponent(Entity, T):添加一个共享组件。
・AddSharedComponent(EntityQuery, T):添加一个共享组件。
・CreateEntity(EntityArchetype):创建一个实体。
・DestroyEntity(Entity):摧毁一个实体。
・DestroyEntity(EntityQuery):销毁一个实体。
・RemoveComponent(Entity):删除一个组件。
・RemoveComponent(Entity,ComponentType):删除一个组件。
・RemoveComponent(EntityQuery,ComponentType):删除一个组件。
・SetBuffer(Entity):更新缓冲区。
・SetComponent(Entity, T):更新一个组件。
・SetSharedComponent(Entity, T):更新共享组件。
・实例化(实体):创建一个实例。
・ToConcurrent():转换为并行ECB。
・Playback(EntityManager):执行命令。
・Dispose():处理。

各类 EntityCommandBufferSystem 的区别与用途

2.1 BeginInitializationEntityCommandBufferSystem
所属阶段: Initialization(初始化阶段)
执行时机: 在 InitializationSystemGroup 的最开始执行。
用途: 适用于在所有初始化系统运行之前提交命令,例如在初始化前预加载资源或设置初始状态。
示例使用场景: 预加载游戏资源,初始化全局状态。

2.2 EndInitializationEntityCommandBufferSystem
所属阶段: Initialization(初始化阶段)
执行时机: 在 InitializationSystemGroup 的最后执行。
用途: 适用于在所有初始化系统运行之后提交命令,例如生成初始实体或设置初始组件。
示例使用场景: 创建游戏中的初始实体,设置初始组件数据。

2.3 BeginSimulationEntityCommandBufferSystem
所属阶段: Simulation(模拟阶段)
执行时机: 在 SimulationSystemGroup 的最开始执行。
用途: 适用于在模拟逻辑运行之前提交命令,例如重置状态或准备模拟所需的实体和组件。
示例使用场景: 重置游戏逻辑状态,准备模拟所需的实体。

2.4 EndSimulationEntityCommandBufferSystem
所属阶段: Simulation(模拟阶段)
执行时机: 在 SimulationSystemGroup 的最后执行。
用途: 适用于在模拟逻辑运行之后提交命令,例如销毁实体或更新组件数据。
示例使用场景: 销毁不再需要的实体,更新组件数据以反映模拟结果。

2.5 BeginPresentationEntityCommandBufferSystem
所属阶段: Presentation(呈现阶段)
执行时机: 在 PresentationSystemGroup 的最开始执行。
用途: 适用于在渲染之前提交命令,例如更新与渲染相关的组件或准备渲染所需的实体。
示例使用场景: 更新渲染相关的组件,准备渲染所需的实体。

2.6 EndPresentationEntityCommandBufferSystem
所属阶段: Presentation(呈现阶段)
执行时机: 在 PresentationSystemGroup 的最后执行。
用途: 适用于在渲染之后提交命令,例如清理渲染相关的资源或处理后处理效果。
示例使用场景: 清理渲染资源,处理后处理效果。

2.7 FixedStepSimulationEntityCommandBufferSystem
所属阶段: Simulation(模拟阶段),专为固定时间步长设计。
执行时机: 在固定时间步长的模拟阶段执行。
用途: 适用于需要与物理引擎等固定时间步长系统配合的操作,例如处理碰撞事件或物理模拟后的操作。
示例使用场景: 处理物理引擎的碰撞事件,更新与物理模拟相关的组件。

示例:

从System 往Job层传递

partial struct BulletMoverSystem : ISystem
{
    [BurstCompile]
    public void OnCreate(ref SystemState state)
    {
        state.RequireForUpdate<EndSimulationEntityCommandBufferSystem.Singleton>();
    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
            .CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter();

        var job = new BulletMoverJob
        {
            deltaTime = SystemAPI.Time.DeltaTime,
            ECB = ecb,
        };

        var jobHandle = job.ScheduleParallel(state.Dependency);
        jobHandle.Complete();
    }
}

Job中的ECB使用


[BurstCompile]
public partial struct ShootAttackJob : IJobEntity
{
    public EntitiesReferences EntitiesReferences;
    public float DeltaTime;
    public EntityCommandBuffer.ParallelWriter ECB;

    public void Execute([EntityIndexInQuery] int index,
        ref LocalTransform localTransform,
        ref FindTarget findTarget,
        ref ShootAttack shootAttack,
        ref UnitMover unitMover)
    {
        shootAttack.timer -= DeltaTime;
        if (shootAttack.timer > 0f)return;
        shootAttack.timer = shootAttack.timerMax;
		
		//克隆实体
        Entity bulletEntity = ECB.Instantiate(index, EntitiesReferences.bulletPrefabEntity);
        float3 bulletSpawnWorldPosition = localTransform.TransformPoint(shootAttack.bulletSpawnLocalPosition);
        //修改实体组件
        ECB.SetComponent(index, bulletEntity, LocalTransform.FromPosition(bulletSpawnWorldPosition));
        ECB.SetComponent(index, bulletEntity, new Bullet
        {
            speed = 5,
            damageAmount = shootAttack.damageAmount
        });
        //销毁实体
		ECB.DestroyEntity(index, entity);
    }
}

相关文章:

  • C#模拟鼠标点击,模拟鼠标双击,模拟鼠标恒定速度移动,可以看到轨迹
  • 【vitepress】如何搭建并部署自己的博客网站
  • sqlserver中的锁模式 | SQL SERVER如何开启MVCC(使用row-versioning)【启用行版本控制减少锁争用】
  • 基于单片机的智慧农业大棚系统(论文+源码)
  • mysql(community版)压缩包安装教程
  • 【计算机网络】确认家庭网络是千兆/百兆带宽并排查问题
  • 解决电脑问题(5)——鼠标问题
  • Android SharedPreferences 工具类封装:高效、简洁、易用
  • MySql数据库增删改查常用语句命令-MySQL步骤详解教程
  • Docker 的基本概念和优势,以及在应用程序开发中的实际应用
  • (十七) Nginx解析:架构设计、负载均衡实战与常见面试问题
  • windows环境下安装部署dify+本地知识库+线上模型
  • linux安装reids
  • 探索在直播中的面部吸引力预测新的基准和多模态方法
  • Git基础之分支
  • 观看文艺汇演问题
  • YC 孵化项目 Pinch:实时语音翻译视频会议平台;Mistral OCR:能处理多语言多模态复杂文档丨日报
  • 【Linux】详谈 基础I/O
  • linux学习(十)(磁盘和文件系统(索引节点,文件系统,添加磁盘,交换,LVM公司,挂载))
  • c语言笔记 函数参数的等价(上)
  • 中国科学院院士徐春明不再担任山东石油化工学院校长
  • 视觉周刊|纪念苏联伟大卫国战争胜利80周年
  • 汇源果汁发文:经营情况一切正常
  • 图集︱“中国排面”威武亮相
  • 中俄弘扬正确二战史观:缅怀历史,重拾初心,阻止悲剧重演
  • 九家企业与上海静安集中签约,投资额超10亿元