ECS介绍
ECS是一种软件架构模式,由三个元素组成:实体(Entity),组件(Component)和系统(System)(看起来和MVC很相似)。游戏程序分为这三个主要元素,并且通过定义每个系统的责任和关系来管理游戏。
实体代表游戏世界中的事物。实体本身没有特定功能,它们将会被组件填充来成为一个实体。
组件是附加到事物的数据。重点不是对象,而是数据,没有办法操纵它。比如操作游戏的角色时,位置,速度和体力等每个状态都将成为一个组成部分,并与称为“角色”实体相关联。另外,实体中的字段信息也被表示为组件部分。
系统是游戏世界的法则。给定与实体关联的某些组件作为数据输入源,或者更新某些组件的值(可能与输入的组件相同)。随着整个系统更新每一帧,游戏世界也在不断进行。我认为最容易想象的是物理定律。例如,想象一个刚体实体。它的运动基于利用位置和速度两个分量的系统来更新坐标。
粗略地说,系统负责处理,组件负责数据,而实体是一组组的组件,用于过滤系统正在处理的内容。由于系统和数据是完全分开的,因此它与面向对象不兼容。
下面为官方介绍:
实体组件系统(ECS)是Unity面向数据的技术堆栈的核心。顾名思义,ECS包含三个主要部分:
- Entities:填充您的游戏或程序的实体或事物。
- Components:与您的实体相关联的数据,但是应该有数据本身而不是实体来组织。(这种组织上的差异正是面向对象和面向数据的设计之间的关键差异之一)
- Systems:主要逻辑所在,是把Components的数据从当前状态转换为下一个状态的逻辑,例如,一个system可能会通过他们的速度乘以从前一帧到这一帧的时间间隔来更新所有的移动中的entities的位置。
ECS使用介绍
这里就以一个实际案例来介绍下ECS的基本使用
1.Components数据组件
纯数据,不含有其他逻辑行为。 例如:旋转速度,缩放大小之类的。
using Unity.Entities;
public struct MoveSpeedComponent : IComponentData
{
public float mMoveSpeed;//移动速度
}
2. System
主要逻辑所在,根据组件的集合(Enitites)和纯数据(Components)编写对应的逻辑,例如旋转,移动等一些逻辑。
这里我们通过ForEach()方法去遍历所有Entity上的数据组件,并且修改他们的数值!
下面的移动代码种用到了quaternion旋转函数,它是依赖于Unity.Mathematics命名空间的,quaternion为我们提供了极多的关于处理旋转和角度的函数,给我们带来了很大的便利,他为我们提供的欧拉角修改的方式以及四元数修改的方式,对于用不惯四元数修改的旋转的,这无疑是个最好的方式,具体的这里就不一一介绍了。
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
public class MoveSystem : ComponentSystem
{
protected override void OnUpdate()
{
Entities.ForEach((ref MoveSpeedComponent moveCmpt ,ref Translation translation,ref Rotation rotation) =>
{
translation.Value.x += moveCmpt.mMoveSpeed * Time.DeltaTime;
if (translation.Value.x>30)
{
//反转移动速度和旋转
rotation.Value=quaternion.Euler(new float3(0,130,0));
moveCmpt.mMoveSpeed = -math.abs(moveCmpt.mMoveSpeed);
}
else if (translation.Value.x < -30)
{
//反转移动速度和旋转
rotation.Value = quaternion.Euler(new float3(0, -130, 0));
moveCmpt.mMoveSpeed =math.abs(moveCmpt.mMoveSpeed);
}
});
}
}
3.Entity
最后是Entity启动类,他为我们初始化出了我们的Entity,以及Entity原型的创建和数据设置,这个类我把他挂载到在了相机上,方便我们进行初始化。
可以看到我们通过SetComponentData()方法初始化了我们的旋转、移动速度、和出生位置。
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Collections;
using Unity.Transforms;
using Unity.Rendering;
public class EntityMain : MonoBehaviour
{
EntityManager mEentityManager;
[SerializeField]
private Mesh[] mFishMeshArray;//模型Mesh数组
[SerializeField]
private Material[] mFishMaterialArray;//模型材质数组
void Start()
{
mEentityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
//创建原型
EntityArchetype entityArchetype = mEentityManager.CreateArchetype(
typeof(MoveSpeedComponent),
typeof(Translation),
//下面三个实体一定要加不然是看不到实例化的物体的
typeof(RenderBounds),
typeof(RenderMesh),
typeof(LocalToWorld),
//添加旋转数据
typeof(Rotation)
);
//创建实体数组 5000代表就生成5000个
NativeArray<Entity> entityArray = new NativeArray<Entity>(5000, Allocator.Temp);
//创建实体
mEentityManager.CreateEntity(entityArchetype, entityArray);
for (int i = 0; i < entityArray.Length; i++)
{
Entity entity = entityArray[i];
//设置数据
mEentityManager.SetComponentData(entity, new Rotation { Value = quaternion.Euler(0, -130, 0) });
mEentityManager.SetComponentData(entity, new MoveSpeedComponent { mMoveSpeed = UnityEngine.Random.Range(3, 10) });
mEentityManager.SetComponentData(entity, new Translation { Value = new float3(UnityEngine.Random.Range(-20, 20), UnityEngine.Random.Range(-15, 15), UnityEngine.Random.Range(5, 100)) });
int index = UnityEngine.Random.Range(0, 3);
//设置材质和渲染网格
mEentityManager.SetSharedComponentData(entity, new RenderMesh { mesh = mFishMeshArray[index], material = mFishMaterialArray[index] });
}
//一定要记得释放
entityArray.Dispose();
}
}
mEentityManager.CreateEntity() 方法可以为我们创建一个Entity实体,相当于New GameObjcet
mEentityManager.CreateArchetype() 方法可以我们的Entity的原型,相当于AddComponent
mEentityManager.SetComponentData()方法则是可以设置Entity数据组件的初始值
在Entity的Inspector面板我们可以看到我们的数据组件:
我们添加的数据组件都在上面,并且我们修改的数值,也有所变化
一共有三种鱼,每种材质都不同。
并且我们的主要目的是去了解如何使用ECS。
下面是同屏1000条鱼的截图
注意:视屏种的不流畅是录屏软件帧率不够导致的不流畅,并不是因为游戏的帧率不够。
5000只鱼:
<iframe allowfullscreen="true" data-mediaembed="bilibili" id="28QbhAKK-1611593944482" src="https://player.bilibili.com/player.html?aid=713854451"></iframe>DOTS 5000只鱼演示(注意:录屏帧率低导致不流畅)
一万只鱼:
<iframe allowfullscreen="true" data-mediaembed="bilibili" id="vOot7jBt-1611594057137" src="https://player.bilibili.com/player.html?aid=756362967"></iframe>DOTS 10000只鱼演示(注意:录屏帧率低导致不流畅)
15000只鱼:
DOTS 15000千只鱼性能的展示
可以看到当使用三种模型材质的鱼数量一共达到15000只时,并且在位移逻辑和游动动画都在的情况下,我们还能稳定在30多帧,可以说很不错了。
并且我们只是简单写了点代码 开了Burst进行的测试。
意味着我们还有很大的提升空间。
关于ECS的简单使用就到这里了
下一篇:Unity 革命性技术DOST 入门三JobSystem系统
原文地址:https://blog.csdn.net/qq_42461824/article/details/113141736
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。