Unity2018新功能之Entity Component System(ECS)一

版权声明:By XM肖牧 https://blog.csdn.net/yye4520/article/details/82217247

Entities介绍

Entities是Unity2018新引入的一个全新游戏设计框架,我们称之为实体组件系统(Entity Component System,简称ECS),它的出现使我们能够集中精力解决实际问题:构成游戏的数据和行为。它利用了C# Job System和Burst,使我们能够充分利用当今的多核处理器。通过从面向对象的设计转向面向数据的设计,我们将更容易重用代码,也更容易让其他人理解和使用ECS。

在Unity2018引入Entities之前,其实ECS框架早已经出现,但是ECS还是因为守望先锋采用了这个框架才被我们所熟知,后来Git上面出现了一个Entitas的插件可以直接用在Unity上面,我在以前的公司参与过一个项目就是用的Entitas插件。

实体Entity:一个ID,它可以用于间接的组件查找,用于在容器里面遍历。

组件数据ComponentData:存储在实体中的数据。

组件系统ComponentSystem:处理游戏,系统逻辑和行为的地方。

组Group:组件系统运行所需的ComponentData列表,相对于判断条件。

 

Entities和传统的ECS名称对比
Entities名称 传统ECS名称
Entity Entity
ComponentData Component
ComponentSystem System

 

Entities和MonoBehaviour功能对比
Entities MonoBehaviour
Entity GameObject
ComponentData Component的字段变量
ComponentSystem Component的Update方法

 

 

Entities的安装

  1. 点击菜单Window > Packages Manager > All,选择Entities,然后点击Install按钮安装。
  2. 打开PlayerSettings>Other Settings>Scripting Runtime Version,我们选择.Net 4.x Equivalent

注意:安装Entities后会报错是因为Unity默认的Scripting Runtime Version是.Net 3.5 Equivalent,我们改为.Net 4.x Equivalent即可。

Entities的使用

我们用一个简单的例子来讲解一下Entities的使用方法。

我们先用传统的写法写一个Cube的自转。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotationCube : MonoBehaviour {

    public float speed;

    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        transform.Rotate(Vector3.up * speed * Time.deltaTime);
    }
}

接下来我们混合加入ECS,把上面的代码拆分成Component和System。我们先写一个Component,只有一个字段变量。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotationCubeComponent :MonoBehaviour
{
    public float speed;
}

然后我们再写一个System,作为逻辑的处理。首先我们要继承ComponentSystem,然后重写OnUpdate,这里相当于MonoBehaviour的Update,我们在这里处理逻辑。Group则是组件系统运行所需的ComponentData列表,可以随意命名,我们可以在这里写很多不同的Group,作为处理逻辑的条件。GetEntities<Group>()表示获取指定的实体,所有符合条件的实体都将被获取到(这里符合条件的是所有带有RotationCubeComponent组件的实体都将被获取到)。

using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;

public class RotationCubeSystem : ComponentSystem
{
    struct Group
    {
        public RotationCubeComponent  rotation;
        public Transform transform;
    }

    protected override void OnUpdate()
    {
        foreach (var enitites in GetEntities<Group>())
        {
            enitites.transform.Rotate(Vector3.up * enitites.rotation.speed * Time.deltaTime);
        }
    }
}

我们也可以用另外一种方式来写System。Inject表示注入数据,在Unity启动时会自动赋值合适的值

using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;

public class RotationCubeSystem : ComponentSystem
{
    struct Group
    {
        public readonly int Length;
        public ComponentArray<RotationCubeComponent> rotationCubeComponents;
        //public RotationCubeComponent  rotation;
        //public Transform transform;
    }

    [Inject] Group group;

    protected override void OnUpdate()
    {
        //foreach (var enitites in GetEntities<Group>())
        //{
        //    enitites.transform.Rotate(Vector3.up * enitites.rotation.speed * Time.deltaTime);
        //}
        for (int i = 0; i < group.rotationCubeComponents.Length; i++)
        {
            group.rotationCubeComponents[i].transform.Rotate(Vector3.up * group.rotationCubeComponents[i].speed * Time.deltaTime);
        }
    }
}

最后,我们创建一个Cube,附加上GameObjectEntity给他一个实体ID标识,附加上RotationCubeComponent组件,我们把旋转速度调为100,再创建几个Cube并且附加上GameObjectEntity,但不附加RotationCubeComponent组件,运行Unity后发现,带有RotationCubeComponent组件的实体会自转,没有带RotationCubeComponent组件的实体不会自传。

我们讲的这个案例主要是让大家了解ECS这个框架的基本思想和传统的开发思路的区别,即数据和逻辑分离。

我将在下一篇文章中继续深入讲解ECS的框架。

Unity2018新功能之Entity Component System(ECS)二

阅读更多

没有更多推荐了,返回首页