“系统”在基于组件的实体体系结构中的作用是什么?


177

我阅读了很多有关实体组件和系统的文章,并认为将实体当作ID的想法非常有趣。

但是我不知道这在组件方面或系统方面是如何完全起作用的。组件只是由某些相关系统管理的数据对象。碰撞系统使用某些BoundsComponent以及空间数据结构来确定是否发生了碰撞。

到目前为止一切都很好,但是如果多个系统需要访问同一组件怎么办?数据应该存放在哪里?输入系统可以修改实体BoundsComponent,但是物理系统需要访问与某些渲染系统相同的组件。

另外,实体是如何构造的?我读到的很多优点之一是实体构造的灵活性。系统本质上与组件相关联吗?如果要引入一些新组件,是否还必须引入新系统或修改现有系统?

我经常读到的另一件事是,实体的“类型”由其具有的组件来推断。如果我的实体只是一个id,我怎么知道我的机器人实体需要被某个系统移动或渲染并进行修改?

很抱歉发布了很长的帖子(或者至少从我的手机屏幕看来如此)!

Answers:


336

表示和实现实体组件系统的方法有很多种,但这是对一种方法的解释。请记住,没有实体/组件/系统架构的具体定义,因此这只是一种实现。

我将为可能会帮助您的实体/组件/系统架构引入一个类比。让我们考虑一个像钥匙这样的实体。

实体

实体键

按键也有牙齿(深蓝色)。我们实体密钥的牙齿是组成它的组件。您可以通过实体的ID来区分实体,即使它们具有相同的牙齿。那么钥匙适合什么呢?锁 锁是我们的系统。例如,运动系统。

系统

运动系统锁

仅当我们的钥匙的位置和速度都有齿时,锁才起作用。该系统仅处理具有位置和速度的实体。设置这些系统如何识别要处理的实体的方法有多种,但是一种方法是使用long。每个位都保留用于组件类型。对于我们的示例,假设使用4位类型而不是64位长。我们的示例实体将具有所有可用的组件。所以关键是1111。然后,系统正在寻找具有的任何实体11--。(-表示不在乎,因为运动不在乎精灵或健康状况)。它可以通过简单的AND操作检查实体。因此,我们的实体匹配if ((1111 & 1100) == 1100)。如果我迷路了,请查看有关按位运算的更多信息。

如您所见,系统可以访问外部资源。他们可以访问时间,图形,声音等。它们只是一次只需要一把钥匙并处理数据的小型处理器。您会看到运动系统采用速度,增量时间和位置。然后进行一些计算并将结果存储回原位。

实体密钥确实很容易生成。您可以随意添加或删除它们。实体不在乎,这只是对组件进行分组和保存的一种方式。组件之间没有相互依赖性。当系统在组件上运行并使用来自一个组件的数据来更新另一个组件时,就像我们的运动示例一样,组件之间的交互最接近。

让我们看一下另一个系统来帮助巩固这个想法:

绘图系统锁

这是我们的绘图系统。它寻找匹配的组件1-1-。该实体之所以匹配,是因为:((1111 & 1010) == 1010)此外,通过在其位置绘制实体精灵,您可以看到该系统将信息输出到屏幕。

好,再说一遍 让我们看一下另一个实体,看看它到目前为止如何适合我们的示例。

不可移动实体密钥

如您所见,此实体具有较少的附加组件。通过查看它确实具有的组件,看起来它可能像石头一样是静态物品。它只是有一个位置和一个精灵。它不会移动,也不会受到任何健康变化的影响。该实体将产生密钥1010。那么,什么系统在该实体上运行?让我们检查:

反对我们的运动系统: ((1010 & 1100) != 1100)不。好像运动系统不在乎此实体,因为它没有必需的组件。

针对我们的绘图系统: ((1010 & 1010) == 1010)嘿,这是一个匹配。该实体将由绘图系统进行操作。绘制系统将在定义的位置绘制精灵。


希望您能看到现在添加另一个将采用我们的组件并对其进行操作的系统将是多么容易。让我确保我已经解决了您的问题:

如果多个系统需要访问同一组件怎么办?数据应该存放在哪里?

通常,系统一个接一个地运行。他们处理所有符合其要求的实体,然后下一个系统执行相同的操作,依此类推。数据与实体共存。系统中不应该存储任何东西,它只是一个可以转动的锁,关键是信息保留并在锁之间移动的位置。

如何构造实体?系统本质上与组件相关联吗?如果要引入一些新组件,是否还必须引入新系统或修改现有系统?

实体只是组件袋。它们具有唯一的ID和组件列表。系统仅以上述方式绑定到组件。您可以拥有没有可在其上运行的系统的组件,但这毫无意义。同样,您可以拥有正在寻找没有实体拥有的组件的系统。这没有什么意义,因为他们可能只是在等待创建与其锁匹配的实体。因此,是的,如果您引入一个新的组件,那么您将希望创建一个利用该组件的系统。否则,您只是在钥匙上增加了不存在的锁齿。

如果我的实体只是一个id,我怎么知道我的机器人实体需要移动或渲染并因此被某些系统修改?

我想我用long定义实体中包含的组件的键的想法来回答这个问题。您知道因为钥匙适合锁。

!那是一个漫长的帖子!(或者至少从我的大型显示器看来是如此。)


23
这个关键类比确实有助于理解现在的整个想法。卓见!大声笑在您的最后一段:)
bio595 2012年

16
+1对于我所见过的关于实体组件系统的最详尽的解释。:O!
knight666

7
来自我的-1-不是因为这是一个不好的方法,而是因为它被描述为THE方法。然而,在许多系统中,组件和服务没有分离(例如,在Unity中),并且系统还有更简单的方法来让系统知道要处理的实体(只需在创建实体时添加它们)。
Kylotan

37
@Kylotan我确实说过“ 可以通过多种方式来设置这些系统如何识别要处理的实体,但是一种方式是使用long ”此外,我通常会对没有用的答案保留否决权(如悬停文字说)。我认为如果您对所有未涵盖他们正在解决的主题的100%的答案进行投票,那么您将花费大量的时间进行投票。
MichaelHouse

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.