换个姿势撸代码,欢迎来到ECS的世界!

本文介绍了ECS(实体组件系统)的概念,包括实体、组件和系统的基本原理,并通过一个简单的HelloWorld示例展示了如何使用ECS框架进行编程。作者计划通过一系列文章帮助读者掌握ECS,逐步进入游戏开发的编程思想。
摘要由CSDN通过智能技术生成

前言

大家好我是IT侠来了!今天我带来的是ECS系列文章。对,没错这是个系列。

这个系列将帮助各位同学入门ECS,会用ECS框架写游戏。最后说不定你也喜欢上了这种“小众”而又牛b的编程思想。

话不说多,今天这篇文章就是让大家对ECS有一个大概认识,不知道大家准备好没有,此时我只想喊一句超级英雄出发前最喜欢喊的一句:“suit up”!!

欢迎来到ECS的世界

正如标题说的一样,欢迎大家来到ECS的世界。

其实我之前有写过一篇文章来说ECS。但是把所有内容都写到一篇里导致文章很长大家也没有读的欲望了,而且写的也不是很好。

所以这次带来了全新的ECS框架和一个使用ECS框架做的一个小游戏「我胃口贼6」我将一步一步的带着大家进入ECS的世界。

ECS 是啥?

ECS的全称是「Entity Component System」可以译成「实体 组件 系统」这3个概念就是ECS框架不可缺少的组成部分。下面依次来介绍下。

实体

实体它在ECS中扮演的是组件的「载体」,实体是不包含任何数据和业务逻辑的。

它的数据结构很简单只有一个全局唯一的ID。

通过实体就可以访问到身上的组件和组件上面的数据。

组件

组件只包含数据,而且没有能力更新自身的数据。

组件上的数据描述了实体的某一个特征。

想要组件产生作用就必须把组件加载到实体上,单独的组件在ECS框架中是没有任何意义的。换句话说就是:组件是为实体而生的。

系统

系统的工作就是操作实体。

你可以给系统定义它所关心的一个或者多个组件。之后只要是实体上有对应的组件,那么就会被系统捕获到。然后就可以操作这些实体和实体上组件。

引擎(世界)

引擎的存在是为了管理实体,组件和驱动系统运转。

其实我更喜欢把「引擎」叫成「世界」。所有实体,组件,系统都是加载一个「世界」里。可以有很多很多的世界彼此没有交集。就像平行时空一样。

ECS中的Hello World

啥语言的第一个例子都是Hello World 下面我就用ECS框架来实现Hello World。

看不懂代码没关系,只是让大家知道用ECS是如何写Hello World的。

在之后的文章我会慢慢讲解。

  //初始化一个世界
  let ecs = ECS();
  //定义说话系统
  let _talk = ecs.system("TalkSystem",100);
  // 监听有Talk组件的实体
  _talk.on("Talk",function(ent:any){
    console.log(ent.Talk.say);
  });
  // 让系统开始工作
  ecs.startSystems();
  //创建一个实体
  let human = ecs.ent();
  //给这个实体加一个Talk组件 让他说一句 Hello World
  // 下面定义完成之后 Talk系统就会捕获到human实体 并且打印这个实体说的话 - Hello World
  ecs.com("Talk",{say:"Hello World"},human);
  

结束语

本篇文章主要是让大家对ECS框架有个基本认识。

最后用Hello World给本篇文章收一个尾,也为下一篇ECS入门篇开个头。

那么,各位 ECS 入门篇再见。

开发者实践游戏开发、副业挣钱,新的种子又开始发芽!

以下是用 Unity ECS DOTS 实现的简单烟花示例代码: ```csharp using System.Collections.Generic; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; using UnityEngine; public class FireworkSystem : SystemBase { private EntityQuery fireworkQuery; private EntityQuery explosionQuery; protected override void OnCreate() { fireworkQuery = GetEntityQuery(typeof(Firework), typeof(Translation), typeof(Velocity)); explosionQuery = GetEntityQuery(typeof(Explosion), typeof(Translation)); } protected override void OnUpdate() { // 更新烟花位置和速度 Entities.With(fireworkQuery).ForEach((ref Translation translation, ref Velocity velocity) => { velocity.Value += new float3(0, -9.81f, 0) * Time.DeltaTime; translation.Value += velocity.Value * Time.DeltaTime; }).Run(); // 检查烟花是否需要爆炸 Entities.With(fireworkQuery).ForEach((Entity entity, ref Firework firework, ref Translation translation) => { if (translation.Value.y <= firework.Height) { // 生成爆炸粒子 var explosionEntity = EntityManager.CreateEntity(typeof(Explosion), typeof(Translation)); EntityManager.SetComponentData(explosionEntity, new Translation { Value = translation.Value }); EntityManager.DestroyEntity(entity); } }).Run(); // 更新爆炸粒子位置和寿命 Entities.With(explosionQuery).ForEach((Entity entity, ref Explosion explosion, ref Translation translation) => { explosion.Lifetime -= Time.DeltaTime; if (explosion.Lifetime <= 0) { EntityManager.DestroyEntity(entity); } else { var size = explosion.Size * (1 - explosion.Lifetime / explosion.MaxLifetime); translation.Value += explosion.Velocity * Time.DeltaTime; EntityManager.SetComponentData(entity, new Scale { Value = size }); } }).Run(); } } public struct Firework : IComponentData { public float Height; public float3 Velocity; } public struct Explosion : IComponentData { public float Lifetime; public float MaxLifetime; public float3 Velocity; public float Size; } public struct Velocity : IComponentData { public float3 Value; } public class FireworkSpawner : MonoBehaviour { public GameObject fireworkPrefab; private void Update() { if (Input.GetMouseButtonDown(0)) { var mousePosition = Input.mousePosition; var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, 10)); SpawnFirework(worldPosition); } } private void SpawnFirework(float3 position) { var fireworkEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(fireworkPrefab, World.Active); EntityManager.SetComponentData(fireworkEntity, new Translation { Value = position }); EntityManager.SetComponentData(fireworkEntity, new Firework { Height = Random.Range(5f, 15f), Velocity = new float3(Random.Range(-5f, 5f), Random.Range(5f, 15f), Random.Range(-5f, 5f)) }); EntityManager.AddComponentData(fireworkEntity, new Velocity()); } } ``` 这个示例中,我们定义了 `Firework` 和 `Explosion` 两个组件,分别表示烟花和爆炸粒子。在 `FireworkSpawner` 中,我们监听鼠标左键点击事件,然后在鼠标位置生成一个烟花。在 `FireworkSystem` 中,我们使用 `Translation` 和 `Velocity` 组件来更新烟花的位置和速度,并且在烟花达到一定高度时生成爆炸粒子。爆炸粒子的位置和大小会随时间变化,当寿命结束时,会自动销毁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值