Entity(实体):是组件的集合,作为标准的系统对象,仅由唯一的一个id组成,可以理解为过去的GameObject对象
Component(组件):是数据容器,组件包含一个或多个与Entity相关的值字段,仅做数据储存
System(系统):System定义了一切游戏行为,是实际包含逻辑的唯一对象,可以理解为未包含任何数据的MonoBehaviour的集合体
使用Unity ECS有以下优点
1.优化数据布局
使用Unity ECS可以保证所有数据以线性方式储存在储存器中,这意味着系统将以最佳方式访问实体组件
2.多线程代码
纯Unity ECS中的System作为作业实现,并有Unity的新C#作业运行System,新的C#作业系统它允许以安全和简单的方式编写多线程代码
3.Unity Burst编译器
Burst编译器旨在最优的方式编译C#作业代码,据说使用Burst编译器编译一些ECS演示代码理论能达到10ms内实例化100000个实体
1.首先修改Packages目录中的Manifest,修改后内容如下:
{
"dependencies": {
"com.unity.ads": "2.0.8",
"com.unity.analytics": "2.0.16",
"com.unity.package-manager-ui": "1.9.11",
"com.unity.purchasing": "2.0.3",
"com.unity.textmeshpro": "1.2.4",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0",
"com.unity.entities": "0.0.12-preview.8"
},
"registry": "https://packages.unity.com",
"testables": [
"com.unity.collections",
"com.unity.entities",
"com.unity.jobs"
]
}
2.修改.net的版本为.Net 4.x,等待重启Unity
3.打开Windows->Debug->Entity Debugger,拖拽到下方
我们创建一个Cube作为Player,点击Add Component添加GameObjectEntity脚本,然后编写InputComponent脚本,编写代码并添加的Cube上。
代码就这么简单,ECS中Component是数据容器,仅包含与Entity相关的值字段。
using UnityEngine;
public class InputComponent : MonoBehaviour
{
public float Horizontal;
public float Vertical;
}
接下来编写移动的System,我们新建一个MovementSystem,用来做对移动行为的控制System
using UnityEngine;
using Unity.Entities;
public class MovementSystem : ComponentSystem
{
private struct Components
{
public Transform Transform;
public InputComponent InputComponent;
}
protected override void OnUpdate()
{
var deltaTime = Time.deltaTime;
var speed = 5.0f;
//遍历所有的所有包含结构体中组件的Entity
foreach (var e in GetEntities())
{
var vector = new Vector3(e.InputComponent.Horizontal, 0, e.InputComponent.Vertical);
e.Transform.Translate(vector* deltaTime * speed);
}
}
}
然后是InputSystem,代码如下:
using Unity.Entities;
using UnityEngine;
public class InputSystem : ComponentSystem
{
private struct Data
{
//结构体长度,即数据数量
public readonly int Length;
//获取所有包含InputComponent的数组
public ComponentArray InputComponents;
}
//Unity会自动注入满足此字段的对象
[Inject] Data data;
protected override void OnUpdate()
{
var horizontal = Input.GetAxis("Horizontal");
var vertical = Input.GetAxis("Vertical");
for (int i = 0; i < data.Length; i++)
{
data.InputComponents[i].Horizontal = horizontal;
data.InputComponents[i].Vertical = vertical;
}
}
}
我们可以通过过Entity Debuger来查看下信息
我们可以看到InputComponent下成功找到Entity 0这个对象了,说明我们的注入是成功的,然后测试运行下
按下上下左右按键,我们的的方块成功移动起来了,可以看到使用ECS,我们Entity对象上仅仅只有包含数据的Component,而我们无需关心其他System是如何运作的,每个System只关心自己本身的实现就行了。