如何处理ECS游戏中的重复数据,以及更多关于ECS的常见问题
How to handle duplicate data in an ECS game, and more general questions about ECS
我正在阅读关于 ECS 的文章,这些文章显然适合开发游戏。
我运行遇到一个问题,或者一个问题,我举个例子说明一下(这正是我遇到的问题)。
我有多个组件 Boss
、Minion
、Player
、Weapon
、Name
。
首先,我在 Player
组件中添加了一个字段 name
。但是由于这些组件中的每一个都可以命名,所以我很想将其模块化并创建一个 Name
组件。大多数系统不会以相同的方式使用名称,但有些会,主要是 DebugSystem
.
事实上,具有 Player
组件的实体不能具有 Name
组件,但应该具有。
我怎样才能轻松处理这个问题?
即:
- 我只能创建一个包含组件
Name
的实体。
- 当我使用组件
Player
创建实体时,组件 Name
已经存在或者应该自动创建。如果可能的话,直接在另一个组件中使用 entity.GetComponent<Player>().name
. 之类的名称获取名称
理想情况下,名称可以在任何具有名称的组件之间共享。这让我想起了 OOP 中的菱形问题,但 ECS 不就是为了解决这个问题而创建的吗?
问题 1) ECS 中是否有标准方法来处理此问题,还是应该由函数 CreateEntity()
手动处理,该函数在末尾添加缺少的组件?
关于 ECS 的其他一般问题:
我开始是继承实体class,做生产链,如果我正确理解了原理(class本身并不重要,但它会自动创建组件)。然后我创建了一些其他实体 class,但最后它们实际上可能只是组件。最后我什至不知道实体 class 是否应该是可继承的。
问题2)ECS系统中Entityclass是不是没有被继承?
在很多介绍文章中,他们并没有讲组件之间的交互,但是在q/a论坛中,他们通常会提出一个事件驱动系统来解决问题。
问题3)事实上,ECS模式与消息系统模式是不可分离的,应该一起使用(至少在大多数情况下),或者是否有纯粹使用 ECS 模式的解决方案?一些答案说事件完全破坏了 ECS 的优势,其他人则建议它。
问题 4)组件可以包含指向其他组件的指针吗? Components 可以包含指向其他 Entities 的指针吗?我知道大多数答案都说它只是一个工具,没有什么不好的,但我想保留 ECS 的优势,而不违背它的原则。
问题5)系统能有数据吗?我没有找到任何相关信息。我在考虑一个基于回合的游戏,我必须在其中存储回合数。因为数据不是一个具体的组件(它是系统本身的一些数据),我很想 1)创建一个单例组件 GameData
进入一些像全局游戏状态一样的实体 2)将数据放入TurnSystem
,假设一次只能玩一个游戏。
如果在关键循环中很少访问名称字段,我通常会将其视为 no-brainer 以将其放入自己的 Name
组件中。它是最灵活和最高效的解决方案,因为关联的数据是冷的(hot/cold 字段拆分)。如果您将名称字符串字段添加到多个组件类型,这将增加从这些组件之一到下一个组件的步幅,并且更少的组件将适合您的关键系统循环中的缓存行。
Question 1) is there a standard method in ECS to handle this or should this be handled manually by the function CreateEntity() that add missing components at the end ?
如果所有实体都需要名称字段,我会偏向于您的第一个解决方案并在创建实体时自动添加它。如果您想保证此名称组件始终可用,您甚至可以断言以确保名称组件在完全删除之前永远不会从实体中删除。
Question 2) Is the Entity class never inherited in the ECS system ?
我不知道 'never' 但我强烈反对在实体或组件级别将继承混合到 ECS 中。首先,如果您必须处理指向 variable-sized 实体或组件子类型指针的多态基指针,则内存管理会立即变得更加复杂并且难以优化访问模式。
Question 3) Is, in fact, ECS pattern not separable from a Messaging System pattern, and should be used together (at least in most cases), or is there a solution purely with an ECS pattern ? Some answers say Events destroy completly the advantages of ECS, some others advise it.
由你决定。我发现尽可能多地依赖 ECS 通常会更有效率,但在处理一个或多个系统时能够将事件推送到并发队列可能非常有用和实用。
Question 4) Can Components contains pointers to others Components ? Can Components contains pointers to others Entities ? I know that most answer says that it's just a tool and nothing is bad about it but I would like to keep the advantages of ECS without going to the opposite of it's principles.
是的,绝对是。我很难想象你不会这样做的情况,因为即使是带有父子关系的基本运动层次结构也需要 parent/child links 在 entities/components 之间。我倾向于使用 32 位索引来将 64 位架构的内存需求减半,还因为我使用的数据结构可以使指针无效,但不能使索引无效。然而,这可能是大多数非平凡项目中以某种方式将 link 实体或组件组合在一起的常见要求。
Question 5) Can Systems have any data ? I didn't found anything about it. I was thinking about a Turn based game, where I have to store the numbers of Turn. Because the data is not a concrete component (it's some data of the System itself), I am tempted to either 1) Create A Singleton Component GameData into some Entity that act like the global game state 2) Put data into the TurnSystem, with the hypothesis that only one game can play at a time.
您可以尝试将数据塞入通过系统访问的组件中,但我认为允许系统存储一些数据更为实际和务实,例如物理系统的物理缓存,如果它是内部实现细节的话仅与它相关,不需要随场景一起保存。
我正在阅读关于 ECS 的文章,这些文章显然适合开发游戏。
我运行遇到一个问题,或者一个问题,我举个例子说明一下(这正是我遇到的问题)。
我有多个组件 Boss
、Minion
、Player
、Weapon
、Name
。
首先,我在 Player
组件中添加了一个字段 name
。但是由于这些组件中的每一个都可以命名,所以我很想将其模块化并创建一个 Name
组件。大多数系统不会以相同的方式使用名称,但有些会,主要是 DebugSystem
.
事实上,具有 Player
组件的实体不能具有 Name
组件,但应该具有。
我怎样才能轻松处理这个问题?
即:
- 我只能创建一个包含组件
Name
的实体。 - 当我使用组件
Player
创建实体时,组件Name
已经存在或者应该自动创建。如果可能的话,直接在另一个组件中使用entity.GetComponent<Player>().name
. 之类的名称获取名称
理想情况下,名称可以在任何具有名称的组件之间共享。这让我想起了 OOP 中的菱形问题,但 ECS 不就是为了解决这个问题而创建的吗?
问题 1) ECS 中是否有标准方法来处理此问题,还是应该由函数 CreateEntity()
手动处理,该函数在末尾添加缺少的组件?
关于 ECS 的其他一般问题:
我开始是继承实体class,做生产链,如果我正确理解了原理(class本身并不重要,但它会自动创建组件)。然后我创建了一些其他实体 class,但最后它们实际上可能只是组件。最后我什至不知道实体 class 是否应该是可继承的。
问题2)ECS系统中Entityclass是不是没有被继承?
在很多介绍文章中,他们并没有讲组件之间的交互,但是在q/a论坛中,他们通常会提出一个事件驱动系统来解决问题。
问题3)事实上,ECS模式与消息系统模式是不可分离的,应该一起使用(至少在大多数情况下),或者是否有纯粹使用 ECS 模式的解决方案?一些答案说事件完全破坏了 ECS 的优势,其他人则建议它。
问题 4)组件可以包含指向其他组件的指针吗? Components 可以包含指向其他 Entities 的指针吗?我知道大多数答案都说它只是一个工具,没有什么不好的,但我想保留 ECS 的优势,而不违背它的原则。
问题5)系统能有数据吗?我没有找到任何相关信息。我在考虑一个基于回合的游戏,我必须在其中存储回合数。因为数据不是一个具体的组件(它是系统本身的一些数据),我很想 1)创建一个单例组件 GameData
进入一些像全局游戏状态一样的实体 2)将数据放入TurnSystem
,假设一次只能玩一个游戏。
如果在关键循环中很少访问名称字段,我通常会将其视为 no-brainer 以将其放入自己的 Name
组件中。它是最灵活和最高效的解决方案,因为关联的数据是冷的(hot/cold 字段拆分)。如果您将名称字符串字段添加到多个组件类型,这将增加从这些组件之一到下一个组件的步幅,并且更少的组件将适合您的关键系统循环中的缓存行。
Question 1) is there a standard method in ECS to handle this or should this be handled manually by the function CreateEntity() that add missing components at the end ?
如果所有实体都需要名称字段,我会偏向于您的第一个解决方案并在创建实体时自动添加它。如果您想保证此名称组件始终可用,您甚至可以断言以确保名称组件在完全删除之前永远不会从实体中删除。
Question 2) Is the Entity class never inherited in the ECS system ?
我不知道 'never' 但我强烈反对在实体或组件级别将继承混合到 ECS 中。首先,如果您必须处理指向 variable-sized 实体或组件子类型指针的多态基指针,则内存管理会立即变得更加复杂并且难以优化访问模式。
Question 3) Is, in fact, ECS pattern not separable from a Messaging System pattern, and should be used together (at least in most cases), or is there a solution purely with an ECS pattern ? Some answers say Events destroy completly the advantages of ECS, some others advise it.
由你决定。我发现尽可能多地依赖 ECS 通常会更有效率,但在处理一个或多个系统时能够将事件推送到并发队列可能非常有用和实用。
Question 4) Can Components contains pointers to others Components ? Can Components contains pointers to others Entities ? I know that most answer says that it's just a tool and nothing is bad about it but I would like to keep the advantages of ECS without going to the opposite of it's principles.
是的,绝对是。我很难想象你不会这样做的情况,因为即使是带有父子关系的基本运动层次结构也需要 parent/child links 在 entities/components 之间。我倾向于使用 32 位索引来将 64 位架构的内存需求减半,还因为我使用的数据结构可以使指针无效,但不能使索引无效。然而,这可能是大多数非平凡项目中以某种方式将 link 实体或组件组合在一起的常见要求。
Question 5) Can Systems have any data ? I didn't found anything about it. I was thinking about a Turn based game, where I have to store the numbers of Turn. Because the data is not a concrete component (it's some data of the System itself), I am tempted to either 1) Create A Singleton Component GameData into some Entity that act like the global game state 2) Put data into the TurnSystem, with the hypothesis that only one game can play at a time.
您可以尝试将数据塞入通过系统访问的组件中,但我认为允许系统存储一些数据更为实际和务实,例如物理系统的物理缓存,如果它是内部实现细节的话仅与它相关,不需要随场景一起保存。