找回密码
 立即注册
查看: 395|回复: 0

Unity——十分钟上手Unity ECS教程

[复制链接]
发表于 2021-11-16 16:26 | 显示全部楼层 |阅读模式
前言
随着Unity新版本迭代,ECS也逐渐走入大家的视野,甚至有人在Unity官方论坛发问ECS是否已经成熟稳定可以商用。本人也是在学习当中,网上已经有各种深入浅出的说明,但缺乏一个可以跟着敲代码的demo、让人短时间内就能从代码层面了解ECS的教程。
本文就致力于用最简单的方式,让你跟着敲一遍代码就大概知道什么是ECS。
Demo内容
场景里放个球,键盘上下左右控制位移。
实战
1. 新建一个工程,确认你的版本支持ECS,我这里用的是2018.3

修改PlayerSetting->Other Setting->Configuration->Scripting Runtime Version为4.x
接下来在工程的Package目录(Assets同级)放入manifest文件以启用ECS框架
点此获取官方manifest样例
2. 在ECS框架中,原本类似MonoBehavior的职能被拆分成纯数据以及操作数据的系统,所以你将会看到大量xxxComponent,xxxSystem的类。比如接下来我们就要建立一个只带移动方向的移动组件、修改移动方向的输入系统以及控制移动的移动系统。
3. 新建几个C#文件:
表示移动数据的MoveComponent.cs
    using Unity.Entities;    using UnityEngine;    public class MoveComponent : MonoBehaviour    {        public Vector3 moveDir;    }表示移动系统的MoveSystem.cs
using Unity.Entities;using UnityEngine;public class MoveSystem : ComponentSystem{    public struct Filter    {        public Transform tf;          public MoveComponent moveComponent;    }    protected override void OnUpdate()    {        foreach (var entity in GetEntities<Filter>())        {            Vector3 pos = entity.tf.position + entity.moveComponent.moveDir * Time.deltaTime * 3;            entity.tf.position = pos;        }    }}表示输入系统的InputSystem.cs
    using Unity.Entities;    using UnityEngine;    public class InputSystem : ComponentSystem    {        struct Data        {            public ComponentArray<MoveComponent> moveArray;        }        [Inject] private Data _data;        protected override void OnUpdate()        {            for (int i = 0; i < _data.moveArray.Length; ++i)            {                _data.moveArray.moveDir = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);            }        }    }
4. 场景中新建一个球体,添加一个GameObjectEntity组件以及我们刚刚新建的MoveComponent组件


5. 启动游戏,按一下上下左右,是不是可以控制球的移动了?
原理
在上面的例子里,输入系统每帧检测输入,把输入赋给移动组件,_data是包含所有MoveComponent的数组,这个数组是通过[Inject]属性标签注入进去的。这个注入的标签很有意思,它会匹配好里面你需要的组件给你放进去,它的原理我们找时间再深入研究。而移动系统就更简单了,就是遍历所有移动组件,然后根据moveDir去移动它对应的transform。
大概你也注意到了InputSystem和MoveSystem的遍历方式是不一样的,这是为了演示可以有不同的遍历方式。而且要注意,上面例子里MoveComponent继承自MonoBehavior,如果它继承自IComponentData,它就只能是一个struct,而struct并不能够像MoveSystem那样去遍历,而且也不能直接用组件方式添加到一个GameObject上了。
继承自IComponentData的好处自然是让纯数据的组件以及系统与GameObject分离,试想一下你可以同时跑100w个移动的对象,但这些对象却不一定需要一个GameObject,这就是ECS带来性能提升的一大原因。
你可能觉得奇怪,球上只添加了两个组件,怎么就移动了,MoveSystem既没new出来也没拖到什么对象上,谁在激活这些系统?答案是世界,当然这是另一个话题了,在本篇里你只需要知道有个“世界”在运行你写的System就够了,只要你写了个系统继承自ComponentSystem,它就会被执行。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-25 07:54 , Processed in 0.115713 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表