Questions tagged «entity-system»

一种游戏范例,其中游戏对象(实体)由组件组成,并由系统对其进行操作。每个实体都是一个指向特定组件的ID。

1
“系统”在基于组件的实体体系结构中的作用是什么?
我阅读了很多有关实体组件和系统的文章,并认为将实体当作ID的想法非常有趣。 但是我不知道这在组件方面或系统方面是如何完全起作用的。组件只是由某些相关系统管理的数据对象。碰撞系统使用某些BoundsComponent以及空间数据结构来确定是否发生了碰撞。 到目前为止一切都很好,但是如果多个系统需要访问同一组件怎么办?数据应该存放在哪里?输入系统可以修改实体BoundsComponent,但是物理系统需要访问与某些渲染系统相同的组件。 另外,实体是如何构造的?我读到的很多优点之一是实体构造的灵活性。系统本质上与组件相关联吗?如果要引入一些新组件,是否还必须引入新系统或修改现有系统? 我经常读到的另一件事是,实体的“类型”由其具有的组件来推断。如果我的实体只是一个id,我怎么知道我的机器人实体需要被某个系统移动或渲染并进行修改? 很抱歉发布了很长的帖子(或者至少从我的手机屏幕看来如此)!

9
实体沟通如何工作?
我有两个用户案例: 如何将entity_A发送take-damage消息entity_B? 如何entity_A查询entity_B的HP? 到目前为止,这是我遇到的情况: 消息队列 entity_A创建一条take-damage消息并将其发布到entity_B的消息队列中。 entity_A创建一条query-hp消息并将其发布到entity_B。 entity_B作为回报,创建一条response-hp消息并将其发布到entity_A。 发布/订阅 entity_B订阅take-damage消息(可能具有一些抢先过滤功能,因此仅传递相关消息)。 entity_A产生take-damage引用消息entity_B。 entity_A订阅update-hp消息(可能已过滤)。每个帧都entity_B广播update-hp消息。 信号/插槽 ??? entity_A将update-hp插槽连接到entity_B的update-hp信号。 有更好的东西吗?我对这些通信方案如何与游戏引擎的实体系统联系起来有正确的理解吗?

1
实际使用基于组件的实体系统
昨天,我阅读了GDC Canada上有关属性/行为实体系统的演示,我认为它很棒。但是,我不确定如何实践地使用它,而不仅仅是理论上的。首先,我将快速向您解释该系统的工作方式。 每个游戏实体(游戏对象)都由属性(=数据,可以通过行为,也可以通过“外部代码”访问)和行为(=逻辑,包含OnUpdate()和OnMessage())组成。因此,例如,在Breakout克隆中,每个积木将由(例如!)组成:PositionAttribute,ColorAttribute,HealthAttribute,RenderableBehaviour,HitBehaviour。最后一个看起来像这样(这只是一个用C#编写的无效示例): void OnMessage(Message m) { if (m is CollisionMessage) // CollisionMessage is inherited from Message { Entity otherEntity = m.CollidedWith; // Entity CollisionMessage.CollidedWith if (otherEntity.Type = EntityType.Ball) // Collided with ball { int brickHealth = GetAttribute<int>(Attribute.Health); // owner's attribute brickHealth -= otherEntity.GetAttribute<int>(Attribute.DamageImpact); SetAttribute<int>(Attribute.Health, brickHealth); // owner's attribute // …

3
在实体组件系统引擎中,如何处理相关实体组?
在研究了几种游戏设计模式之后,我为我的游戏引擎选择了Entity-Component-System(ES System)。我正在阅读文章(主要是T = Machine)并查看一些源代码,我认为我已经足够入门。 我正在努力的只有一个基本想法。如何处理相互依赖的实体组? 让我举一个例子: 假设我正在制作一个标准的空中射击游戏(例如Jamestown),并且我想构造一个具有多个不同但相互连接的部分的“老板实体”。分解可能看起来像这样: 船体:运动,渲染 大炮:位置(相对于舰体锁定),向英雄追踪\开火,受到伤害直到被禁用 核心:位置(相对于舰体锁定),向英雄追踪\射击,对伤害造成伤害直到被禁用,对舰组中的所有其他实体禁用(毁灭) 我的目标是将某些东西识别(并操纵)为独特的游戏元素,而不必每次我要构建新的聚合元素时都必须重写子系统。 如何在ES系统中实施这种设计? 我是否实现某种父子实体关系(实体可以有孩子)?这似乎与实体只是空容器的方法相矛盾,并使其感觉更面向对象。 我是否将它们实现为具有某些连接组件(BossComponent)和相关系统(BossSubSystem)的单独实体?我不禁认为这将很难实现,因为组件之间的通信方式似乎是一个巨大的陷阱。 我是否将它们实现为一个具有一组组件(ShipComponent,CannonComponents,CoreComponent)的实体?这似乎改变了ES System的意图(这里的组件似乎太像重量级的实体),但是我知道这一点,所以我想我会把它放在那儿。 我是否将它们实现为我提到的其他内容? 我知道在OOP中可以很容易地实现这一点,但是我选择坚持使用ES而不是OOP是我会坚持的。如果我需要打破纯粹的ES理论来实现此设计,我会(不像我以前没有折衷过纯粹的设计),但是出于性能原因,我宁愿这样做,而不是从糟糕的设计开始。 为了获得额外的荣誉,请考虑相同的设计,但是实际上每个“老板实体”都连接到由主体,主要核心和3个“老板实体”组成的更大的“ BigBoss实体”。这将使我看到至少3个维度的解决方案(祖父母-父母子女)...对我来说应该绰绰有余。

4
C ++中的实体/组件系统,如何发现类型并构造组件?
我正在使用C ++构建实体组件系统,希望遵循Artemis的风格(http://piemaster.net/2011/07/entity-component-artemis/),因为组件主要是数据包,包含逻辑的系统。我希望利用这种方法的以数据为中心的优势,并构建一些不错的内容工具。 但是,我遇到的一个难题是如何从数据文件中获取一些标识符字符串或GUID,并使用该标识符或实体来构造实体的组件。显然,我可以拥有一个大型解析函数: Component* ParseComponentType(const std::string &typeName) { if (typeName == "RenderComponent") { return new RenderComponent(); } else if (typeName == "TransformComponent") { return new TransformComponent(); } else { return NULL: } } 但这真的很丑。我打算经常添加和修改组件,并希望构建某种ScriptedComponentComponent,以便您可以在Lua中实现组件和系统以进行原型设计。我希望能够编写一个从某个类继承的BaseComponent类,也许将其扔进几个宏中以使一切正常工作,然后使该类可在运行时实例化。 在C#和Java中,这将非常简单,因为您获得了不错的反射API来查找类和构造函数。但是,我正在用C ++进行此操作,因为我想提高自己在该语言中的熟练程度。 那么用C ++如何做到这一点呢?我已经阅读了有关启用RTTI的信息,但似乎大多数人对此保持警惕,尤其是在我只需要将其用于对象类型的子集的情况下。如果在那里需要定制的RTTI系统,该从哪里开始学习编写一个系统?

1
实体系统的缓存效率如何?
最近,我已经做了大量关于实体系统的阅读,以在我的C ++ / OpenGL游戏引擎中实现。我经常听到称赞的关于实体系统的两个主要好处是 由于不必纠缠复杂的继承层次结构,因此可以轻松地构造新类型的实体,并且 缓存效率,这让我很难理解。 当然,理论很简单;每个组件都连续存储在一块内存中,因此关心该组件的系统可以遍历整个列表,而不必在内存中跳转并杀死缓存。问题是我真的无法想到实际可行的情况。 首先,让我们看一下组件的存储方式以及它们之间的相互引用。系统需要能够使用多个组件,即渲染系统和物理系统都需要访问变换组件。我已经看到许多解决此问题的可能实现,但没有一个能很好地实现。 您可以让组件存储指向其他组件的指针,或者指向存储实体的指针的实体的指针。但是,一旦您将指针添加到组合中,您就已经失去了缓存效率。您可以确保每个组件数组都为'n'个大数组,其中'n'为系统中存在的实体数量,但是这种方法浪费内存。这使得很难向引擎中添加新的组件类型,但是仍然会浪费缓存效率,因为您要从一个数组跳到另一个数组。您可以交错实体数组,而不是保留单独的数组,但是您仍然在浪费内存。使得添加新组件或系统的成本高得惊人,但是现在有了使所有旧级别失效并保存文件的额外好处。 所有这些都假定在列表,每一帧或每笔价格变动中对实体进行线性处理。实际上,情况并非如此。假设您使用扇形/门户渲染器或八叉树来执行遮挡剔除。您也许可以在一个扇区/节点内连续存储实体,但是无论您是否喜欢它都将四处走动。然后,您将拥有其他系统,它们可能更喜欢以其他顺序存储的实体。在开始使用AI LOD之前,AI可以将实体存储在一个很大的列表中。然后,您需要根据与玩家之间的距离或其他一些LOD指标来拆分该列表。物理学将要使用该八叉树。脚本无关紧要,无论如何,它们都需要运行。 我可以看到在“逻辑”(例如ai,脚本等)和“世界”(例如渲染,物理,音频等)之间拆分组件,并分别管理每个列表,但是这些列表仍然必须彼此交互。如果AI不能影响用于实体渲染的变换或动画状态,则AI是没有意义的。 实体系统在现实游戏引擎中如何“高效缓存”?也许有一种混合方法,每个人都在使用而不是谈论,例如将实体全局存储在数组中并在八叉树中引用它?

5
如何在实体系统中实现功能?
询问实体系统(两个问题后1,2),并阅读一些文章在他们身上,我想我理解他们比以前好多了。我仍然有一些不确定性,主要是关于构建粒子发射器,输入系统和相机。我显然在理解实体系统方面仍然存在一些问题,它们可能适用于其他所有对象,但是我选择这三个对象是因为它们是非常不同的概念,应该涵盖相当广泛的领域,并有助于我理解实体系统以及如何理解实体系统。我自己会在遇到这些问题时处理这些问题。 我正在用JavaScript构建引擎,并且已经实现了大多数核心功能,其中包括:输入处理,灵活的动画系统,粒子发射器,数学类和函数,场景处理,相机和渲染以及一大堆引擎通常支持的其他功能。我阅读了Byte56的回答,这使我对将引擎制作为实体系统感兴趣。它仍将是具有基本场景概念的HTML5游戏引擎,但它应支持从组件动态创建实体。 我现在遇到的问题是将我的旧引擎概念适合这种新的编程范例。这些是以前的问题中的一些定义,这些定义已更新: 一个实体是一个标识符。它没有任何数据,它不是对象,它是一个简单的ID,代表所有实体的场景列表中的索引(我实际上计划将其实现为组件矩阵)。 甲组件是一个数据保持器,但是具有可以对数据进行操作的方法。最好的示例是Vector2D或“位置”组件。它具有data:x和y,还有一些使对数据进行操作更容易的方法:add(),normalize()等。 一个系统的东西,可以对一组满足某些要求的实体的操作; 通常,实体需要具有一组特定的组件才能进行操作。系统是“逻辑”部分,是“算法”部分,组件提供的所有功能纯粹是为了简化数据管理。 相机 相机具有Vector2Dposition属性,rotation属性以及一些将其围绕点定中心的方法。每帧都将其与场景一起馈入渲染器,并且所有对象均根据其位置进行平移。然后渲染场景。 我如何在实体系统中表示这种对象?摄像机是实体,组件还是组合(按照我的回答)? 粒子发射器 我的粒子发射器遇到的问题还是,应该是什么。我非常确定粒子本身不应该是实体,因为我想支持超过10,000个粒子,而且我相信创建这么多实体将对我的性能造成沉重打击。 我如何在实体系统中表示这种对象? 输入管理员 我要谈的最后一个是如何处理输入。在我当前的引擎版本中,有一个名为的类Input。它是一个处理程序,订阅浏览器的事件,例如按键和鼠标位置更改,并且还维护内部状态。然后,播放器类具有一个react()方法,该方法接受输入对象作为参数。这样做的好处是可以将输入对象序列化为.JSON,然后在网络上共享,从而实现流畅的多人模拟。 这如何转化为实体系统?

3
如何在基于组件的实体系统中正确实现消息处理?
我正在实现一个具有以下内容的实体系统变体: 一个实体类是多一点的ID结合部件一起 一堆没有“组件逻辑” 的组件类,只有数据 一堆系统类(又名“子系统”,“管理器”)。这些完成所有实体逻辑处理。在大多数基本情况下,系统只是遍历它们感兴趣的实体列表并对其进行操作 甲MessageChannel类对象被所有的游戏系统共享。每个系统都可以订阅特定类型的消息以进行收听,还可以使用该频道将消息广播到其他系统 系统消息处理的初始变体是这样的: 依次在每个游戏系统上运行更新 如果系统对某个组件执行了某些操作,而其他系统可能对此操作感兴趣,则该系统会发送一条适当的消息(例如,系统调用 messageChannel.Broadcast(new EntityMovedMessage(entity, oldPosition, newPosition)) 每当实体移动时) 订阅特定消息的每个系统都会得到其消息处理方法,称为 如果系统正在处理事件,并且事件处理逻辑要求广播另一条消息,则立即广播该消息,并调用另一条消息处理方法链 在我开始优化碰撞检测系统之前,这个变体是可以的(随着实体数量的增加,它变慢了)。首先,它只是使用简单的蛮力算法迭代每个实体对。然后,我添加了一个“空间索引”,该索引具有一个单元格网格,该网格存储特定单元格区域内的实体,因此仅允许对相邻单元格中的实体进行检查。 实体每次移动时,碰撞系统都会检查该实体是否与新位置的物体发生碰撞。如果是,则检测到冲突。并且,如果两个碰撞的实体都是“物理对象”(它们都具有RigidBody分量,并且打算彼此推开以免占据相同的空间),则专用的刚体分离系统会要求运动系统将实体移动到某个将他们分开的特定职位。这进而导致运动系统发送消息,通知已更改的实体位置。碰撞检测系统旨在做出反应,因为它需要更新其空间索引。 在某些情况下,这会引起问题,因为单元的内容(C#中的Entity对象的通用列表)在进行迭代时会被修改,从而导致迭代器抛出异常。 那么... 如何防止碰撞系统在检查碰撞时被打断? 当然,我可以添加一些“聪明” /“棘手”逻辑来确保正确地迭代单元格内容,但是我认为问题不在于碰撞系统本身(在其他系统中也存在类似问题),而是消息在系统之间传播时得到处理。我需要某种方式来确保特定的事件处理方法能够正常工作,而不会造成任何干扰。 我尝试过的 传入消息队列。每当某个系统广播消息时,该消息就会被添加到对该消息感兴趣的系统的消息队列中。当每帧调用系统更新时,将处理这些消息。问题是:如果系统A将消息添加到系统B的队列中,则如果系统B的更新要晚于系统A(在同一游戏框架中),则它工作良好;否则,它将导致该消息处理下一个游戏框架(某些系统不希望使用) 传出邮件队列。当系统处理事件时,它将广播的所有消息添加到传出消息队列中。消息无需等待系统更新被处理:在初始消息处理程序完成工作后,它们将立即得到处理。如果对消息的处理导致其他消息被广播,它们也将添加到传出队列中,因此所有消息都在同一帧中进行处理。问题:如果实体生存期系统(我用一个系统实现了实体生存期管理)创建了一个实体,它将通知某些系统A和B。当系统A处理该消息时,它将导致一系列消息,这些消息最终导致所创建的实体被破坏(例如,在与某个障碍物碰撞的位置处创建了一个项目符号实体,这会导致项目符号自毁)。在解析消息链时,系统B没有获得实体创建消息。因此,如果系统B也对实体破坏消息感兴趣,它将得到它,并且只有在“链”完成解析之后,它才会得到初始实体创建消息。这将导致销毁消息被忽略,创建消息被“接受”, 编辑-回答问题,评论: 碰撞系统迭代时,谁修改了单元格的内容? 当碰撞系统正在对某个实体及其邻居进行碰撞检查时,可能会检测到碰撞,并且该实体系统将发送一条消息,其他系统立即对此进行响应。对消息的反应可能导致其他消息被创建并立即处理。因此,即使先前的碰撞检查尚未完成,其他一些系统也可能会创建一条消息,表明碰撞系统随后需要立即进行处理(例如,移动了一个实体,因此碰撞系统需要更新其空间索引)。 您不能使用全局传出消息队列吗? 我最近尝试了一个全局队列。它引起新的问题。问题:我将储罐实体移动到墙实体(储罐由键盘控制)。然后我决定改变坦克的方向。为了将水箱和墙壁的每个框架分开,CollidingRigidBodySeparationSystem将水箱从墙壁上移开的最小可能量。分离方向应与水箱的移动方向相反(游戏图纸开始时,水箱应看起来好像从未移入墙壁)。但是方向变成了与新方向相反的方向,因此将储罐移动到与最初不同的另一侧。发生问题的原因:这是现在处理消息的方式(简化代码): public void Update(int deltaTime) { m_messageQueue.Enqueue(new TimePassedMessage(deltaTime)); while (m_messageQueue.Count > 0) { Message message = m_messageQueue.Dequeue(); this.Broadcast(message); } } …

5
在基于组件的系统中上电
我才刚刚真正开始着手基于组件的设计。我不知道这样做的“正确”方法是什么。 这是场景。玩家可以装备盾牌。盾牌被绘制为气泡围绕玩家,它具有单独的碰撞形状,并减少了玩家从区域效果中受到的伤害。 在基于组件的游戏中如何设计这样的盾牌? 让我感到困惑的是,屏蔽罩显然具有三个与之关联的组件。 减少伤害/过滤 一个精灵 对撞机。 更糟的是,不同的防护罩变体可能具有更多的行为,所有这些行为都可能是以下因素: 提高玩家的最大健康度 健康再生 弹丸变形 等等 我在想这个吗?盾牌应该只是超级组件吗? 我真的认为这是错误的答案。因此,如果您认为这是要走的路,请解释一下。 盾牌应该是自己的实体来跟踪玩家的位置吗? 这可能使实施损害过滤变得困难。这也模糊了附加组件和实体之间的界线。 屏蔽是否应该是容纳其他组件的组件? 我从未见过或听到过这样的消息,但也许很常见,但我还不够深入。 盾牌应该只是添加到播放器中的一组组件吗? 可能还有一个额外的组件来管理其他组件,例如,这样它们就可以作为一个组全部删除。(偶然地留下减少伤害的部分,这很有趣)。 对于具有更多组件经验的人来说,还有其他明显的东西吗?

4
对于基于组件的体系结构,适当的粒度级别是多少?
我正在开发具有基于组件的体系结构的游戏。一个Entity拥有一组Component实例,每个实例都有一组Slot用于存储,发送和接收值的实例。工厂功能,例如Player具有所需组件和插槽连接的生产实体。 我正在尝试确定组件的最佳粒度。例如,现在Position,Velocity和Acceleration都是串联的独立组件。Velocity并且Acceleration可以轻松地重写为统一的Delta组件或Position,Velocity并且Acceleration可以与诸如Friction和Gravity组成整体Physics组件。 一个组件应该承担最小的责任(以大量的互连为代价),还是应该将相关组件组合为整体组件(以灵活性为代价)?我倾向于前者,但我可以使用第二种意见。

6
用户友好但仍然灵活的基于组件的实体系统有哪些设计?
我对基于组件的实体系统感兴趣已有一段时间了,并阅读了无数文章(Insomiac游戏,相当标准的Evolve Your Hierarchy,T-Machine,Chronoclast ...等)。 它们似乎都在某种东西的外部具有结构: Entity e = Entity.Create(); e.AddComponent(RenderComponent, ...); //do lots of stuff e.GetComponent<PositionComponent>(...).SetPos(4, 5, 6); 而且,如果您引入了共享数据的概念(这是到目前为止我所见过的最好的设计,因为这并不是在所有地方都复制数据) e.GetProperty<string>("Name").Value = "blah"; 是的,这非常有效。但是,它并不是最简单的读写方法。感觉很笨拙,而且对您不利。 我个人想做这样的事情: e.SetPosition(4, 5, 6); e.Name = "Blah"; 当然,获得这种设计的唯一方法是回到Entity-> NPC-> Enemy-> FlyingEnemy-> FlyingEnemyWithAHatOn这种设计试图避免的层次结构。 有没有人看到这种组件系统的设计既灵活又保持了用户友好性?就此而言,设法以一种很好的方式解决(可能是最困难的问题)数据存储? 用户友好但仍然灵活的基于组件的实体系统有哪些设计?

5
改善O(N ^ 2)函数(所有实体迭代所有其他实体)
有一点背景知识,我正在和一个C ++的朋友一起编写一个演化游戏,使用ENTT作为实体系统。生物在2D地图中四处走走,吃些绿色或其他生物,繁殖并改变其特性。 此外,当实时运行游戏时,性能还不错(60fps没问题),但我希望能够显着加快速度,而不必等待4小时即可看到任何重大变化。所以我想尽快得到它。 我正在努力寻找一种有效的方法来让生物找到食物。每个生物都应该寻找最接近它们的最佳食物。 如果要吃东西,应该以中心位置为中心的生物以149.64半径(视野距离)环顾四周,并根据营养,距离和种类(肉或植物)来判断应选择哪种食物。 。 负责查找每个生物食物的功能正在消耗大约70%的运行时间。简化当前的编写方式,它是这样的: for (creature : all_creatures) { for (food : all_entities_with_food_value) { // if the food is within the creatures view and it's // the best food found yet, it becomes the best food } // set the best food as the target for creature …

2
基于组件的系统在线资源
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 2年前关闭。 我一直在考虑在游戏中采用基于组件的方法。其他人是否有任何体面的参考资料或示例实现方式将有助于使这种过渡变得容易一些?

2
如何正确访问C ++实体组件系统中的组件?
(我正在描述的内容基于此设计:什么是实体系统框架?,向下滚动即可找到它) 我在用C ++创建实体组件系统时遇到了一些问题。我有我的Component类: class Component { /* ... */ }; 实际上是要创建其他组件的接口。因此,要创建自定义组件,我只需实现接口并添加将在游戏中使用的数据: class SampleComponent : public Component { int foo, float bar ... }; 这些组件存储在Entity类中,该类为Entity的每个实例提供唯一的ID: class Entity { int ID; std::unordered_map<string, Component*> components; string getName(); /* ... */ }; 通过哈希组件的名称将组件添加到实体(这可能不是一个好主意)。当我添加一个自定义组件时,它被存储为组件类型(基类)。 现在,另一方面,我有一个System接口,它在内部使用Node接口。Node类用于存储单个实体的某些组件(因为系统对使用实体的所有组件不感兴趣)。当系统必须使用时update(),它仅需要遍历由不同实体创建的存储节点。所以: /* System and Node implementations: (not the interfaces!) */ class …

3
如何在实体系统中编码UI / HUD?
我想我已经得到了亚当·马丁(t-machine)启发的实体系统的想法。我想开始在下一个项目中使用它。 我已经知道实体,组件和系统的基本知识。我的问题是如何处理UI / HUD。例如,任务窗口,技能窗口,角色信息窗口等。您如何处理UI事件(例如,按下按钮)?这些是不需要每帧都进行处理的东西。目前,我正在使用MVC编写UI,但我认为这与实体系统不兼容。 我读过,实体系统嵌入在更大的OOP中。我不知道UI是否在ES之外。我该如何处理?

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.