Unity ECS学习笔记(一) 初探

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<Components>())
        {
            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<InputComponent> 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只关心自己本身的实现就行了。

猜你喜欢

转载自blog.csdn.net/RinKas/article/details/81114263