Unity DOTS 从入门到精通之传统 Unity 设计转换为 DOTS 设计
文章目录
- 前言
- 传统 Unity 设计与 DOTS 设计
- 安装 DOTS 包
- 常规Unity设计
- DOTS 设计
前言
作为 DOTS 教程,我们将创建一个旋转立方体的简单程序,并将传统的 Unity 设计转换为 DOTS 设计。
- Unity 2022.3.52f1
- Entities 1.3.10
传统 Unity 设计与 DOTS 设计
在本教程中,我们将介绍将“ GameObject + MonoBehaviour ”转换为“ Entity + Component + System ”的过程。
安装 DOTS 包
要安装 DOTS 包,请按照以下步骤操作:
(1)从菜单“窗口 → 包管理器”打开包管理器。
(2)搜索“ Entities” 并安装 Entities和Entities Graphics。
(3)搜索“ Universal RP” 并安装 Universal RP,并设置Graphics/Scriptable Render Pipeline Settings。
这会添加“实体”作为依赖项,并递归添加它所依赖的关联包( Burst、Collections、Jobs、Mathematics等)。
常规Unity设计
首先,我们将使用传统的 Unity 设计创建一个旋转立方体的程序。
(1)在Unity中创建一个项目。
(2)在层次结构窗口中,通过选择“+ → 3D 对象 → 立方体”添加一个立方体。
(3)将脚本“Rotator”添加到Cube中,并进行如下编辑。
using UnityEngine;
public class Rotator : MonoBehaviour
{
public float speed;
void Update()
{
transform.Rotate(0f, speed * Time.deltaTime, 0f);
}
}
(4)在 Inspector 窗口中,将“Rotator”的“Speed”设置为 180(每秒旋转 180 度)。
(5)执行。
DOTS 设计
接下来,我们将传统的 Unity 设计转换为 DOTS 设计。
(1)新建一个New Sub Scene
因为在Dots中 SubScene 相当于是在多线程中运行,所以Dots的游戏对象都需要放到NewSubScene中。而非Dot的游戏对象需要放到主场景中。
(2)新建一个Cube并放到New Sub Scene中
(3)编写脚本RotatorAuthoring.cs,向Cube中添加“ RotatorAuthoring”组件。
using System.Collections;
using UnityEngine;
using Unity.Entities;
public class RotatorAuthoring : MonoBehaviour
{
public float Speed;
//将 MonoBehaviour 的 RotatorAuthoring 组件数据(如 Speed)
//转换为 ECS 的 Rotator 组件数据(IComponentData)
public class RotatorBaker : Baker<RotatorAuthoring>
{
public override void Bake(RotatorAuthoring authoring)
{
var entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new Rotator { speed = authoring.Speed });
}
}
}
//旋转数据类
public struct Rotator : IComponentData
{
public float speed;
}
(4)创建脚本“RotatorSystem.cs”
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
// 旋转逻辑系统(每帧执行)
public partial struct RotatorSystem : ISystem
{
public void OnUpdate(ref SystemState state)
{
float deltaTime = SystemAPI.Time.DeltaTime;
// 遍历所有拥有 Rotator 和 LocalTransform 的实体
foreach (var (rotator, transform) in
SystemAPI.Query<RefRO<Rotator>, RefRW<LocalTransform>>())
{
// 计算旋转量(弧度制)
float radiansPerSecond = math.radians(rotator.ValueRO.speed);
float rotationAmount = radiansPerSecond * deltaTime;
// 绕 Y 轴旋转
transform.ValueRW.Rotation = math.mul(
transform.ValueRO.Rotation,
quaternion.Euler(0, rotationAmount, 0)
);
}
}
}
SystemAPI.Query<RefRO, RefRW>(),这句话是用来查询当前场景中,所有含有Rotator组件的Entitiy实体的。
(5)执行。
立方体旋转,就像传统的 Unity 设计一样。
您可以通过Entities Hierarchy来查看Dots模式下的所有游戏对象
(6)还可以在Inspector面板,切换显示Cube的Dots模式组件
选择Automatic 为Mono模式组件
选择Runtime 为Dots模式组件
我们可以看到Cube上面有很多系统组件,当然也包括我们的Rotator组件。
(7)查看Entities/System面板,
可以看到当前正在运行的RotatorSystem。
System类是不需要添加到任何 游戏对象上的,只要是工程中的System类,默认都会自动运行。