微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在ECS游戏中处理重复数据,以及有关ECS的更多一般性问题

如何解决如何在ECS游戏中处理重复数据,以及有关ECS的更多一般性问题

我正在阅读有关ECS的文章,这些文章显然很适合开发游戏。

我遇到了一个问题或一个问题,我将在示例中对此进行说明(这正是我遇到的问题)。

我有多个分量BossMinionPlayerWeaponName。 首先,我在name组件中添加一个字段Player。但是由于可以命名所有这些组件,所以我很想对其进行模块化并创建一个Name组件。大多数系统不会以相同的方式使用名称,但有些会主要使用DebugSystem

事实是具有Player组件的实体不能具有Name组件,但应该具有。 我该如何轻松处理?

那是:

  • 我只能创建一个组件为Name的实体。
  • 当我使用组件Player创建实体时,组件Name已经存在或应自动创建。如果可能的话,请使用entity.GetComponent<Player>().name之类的名称直接在另一个组件中获取名称

理想情况下,名称可以在具有名称的任何组件之间共享。它使我想起了OOP中的钻石问题,但是ECS是否不是部分创建来解决此问题?

问题1) ECS中是否有标准方法可以处理此问题,或者应该由功能CreateEntity()手动处理该功能,并在末尾添加缺少的组件?

关于ECS的其他一般问题:

如果我正确理解了原理(从类本身并不重要,但是它会自动创建组件),那么我将从Entity类继承开始,以建立生产链。然后,我创建了其他一些Entity类,但最终它们实际上可能只是Components。最后,我什至不知道Entity类是否应该可继承。

问题2)实体类是否从未在ECS系统中继承?

在许多介绍文章中,他们没有谈论组件之间的交互,但是在q / a论坛中,他们通常提出了事件驱动系统来解决问题。

问题3):实际上,ECS模式不能与消息系统模式分开,并且应该一起使用(至少在大多数情况下),或者是否有ECS解决方案?模式?有些回答说“事件”完全摧毁了ECS的优势,而另一些人则建议这样做。

问题4):组件可以包含指向其他组件的指针吗?组件可以包含指向其他实体的指针吗?我知道大多数答案都说这只是一种工具,对此没有什么不好,但我想保留ECS的优势,而不必违背其原理。

问题5)系统可以有任何数据吗?我什么都没找到。我在考虑一个基于回合的游戏,我必须在其中存储回合的数量。由于数据不是具体的组成部分(它是系统本身的一些数据),因此我倾向于以下两种情况之一:1)将单例组件GameData创建为行为类似于全局游戏状态的某些实体2)将数据放入TurnSystem,并假设一次只能玩一场游戏。

解决方法

如果名称字段很少在关键循环中访问,我通常会把它放在自己的Name组件中是理所当然的。这是最灵活,最高效的解决方案,因为关联的数据是冷数据(热/冷字段拆分)。如果将名称字符串字段添加到多个组件类型,则将增加从这些组件之一到下一个组件的步伐,并且这些组件中的更少组件将适合关键系统循环中的缓存行。

问题1)ECS中是否有标准方法可以处理此问题,还是应该由功能CreateEntity()手动处理该方法,该方法会在末尾添加缺少的组件?

如果所有实体都需要一个名称字段,那么我会偏向您的第一个解决方案,只是在创建实体时自动添加它。如果您想保证此名称组件始终可用,您甚至可以断言确保名称组件在完全删除之前从未从实体中删除。

问题2)实体类是否从未在ECS系统中继承?

我对“从不”一无所知,但我强烈反对在实体或组件级别将继承混入ECS。首先,如果必须处理指向可变大小的实体或组件子类型指针的多态基址指针,则内存管理将变得非常复杂,并且在访问模式方面难以优化。

问题3)实际上,ECS模式是否与消息系统模式不可分离,是否应该一起使用(至少在大多数情况下),还是仅使用ECS模式有解决方案?有些回答说“事件”完全摧毁了ECS的优势,而另一些人则建议这样做。

由您决定。我发现通常尽可能多地依靠ECS更有效率,但是在处理一个或多个系统时将事件推送到并发队列中将是非常有用和实用的。

问题4)组件可以包含指向其他组件的指针吗?组件可以包含指向其他实体的指针吗?我知道大多数答案都说这只是一种工具,对此没有什么不好,但我想保留ECS的优势,而不必违背其原理。

是的,绝对。对于我来说,很难想象您不会那样做,因为即使具有父项的基本运动层次结构也需要实体/组件之间的父子链接。我倾向于使用32位索引来将64位体系结构上的内存需求减少一半,还因为我使用的数据结构可以使指针无效,但不能使索引无效。但这在大多数非同寻常的项目中可能是将实体或组件以某种方式链接在一起的普遍要求。

问题5)系统可以有任何数据吗?我什么都没找到。我在考虑一个基于回合的游戏,我必须在其中存储回合的数量。由于数据不是具体的组成部分(它是系统本身的某些数据),因此我倾向于以下两种情况之一:1)将Singleton组件GameData创建为行为类似于全局游戏状态的某些实体2)将数据放入TurnSystem中,假设一次只能玩一场游戏。

您可以尝试将数据塞入可通过系统访问的组件中,但是我认为允许系统存储一些数据更为实用和实用,例如,如果这是内部实现细节,则仅用于物理系统的物理缓存与此相关,并且不需要与场景一起保存。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。