Questions tagged «entity-component»

3
如何在游戏中实现智能脚本编制?
我正在开发一个游戏引擎。它应该是一个基于实体/组件的实体。为了开发游戏本身,我想使用某种脚本语言来实际创建实体。 例如,如果我想添加一种对玩家具有侵略性的怪物,它将是一个具有多个组成部分的实体。这些组件会随着怪物类型的变化而变化,因此,如果我有一百种不同类型的怪物,那么在我的游戏中,我就不必直接在游戏代码中为每个怪物创建新的方法。 我应该使用脚本语言来描述该实体,还是使用组件?更一般而言,我应该如何在游戏中使用脚本?

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 …

1
如何从实体组件系统游戏引擎中的cpu缓存中受益?
我经常阅读ECS游戏引擎文档,这是明智使用cpu缓存的良好架构。 但是我不知道如何从cpu缓存中受益。 如果将组件保存在连续内存中的数组(或池)中,则只有在顺序读取组件的情况下,才是使用cpu缓存BUT的好方法。 当我们使用系统时,它们需要实体列表,这些列表是具有特定类型组件的实体列表。 但是这些列表以随机的方式而不是顺序地提供了组件。 那么如何设计ECS以最大化缓存命中率呢? 编辑: 例如,物理系统需要具有RigidBody和Transform组件的实体的实体列表(有一个RigidBody池和一个Transform组件池)。 因此,其更新实体的循环将如下所示: for (Entity eid in entitiesList) { // Get rigid body component RigidBody *rigidBody = entityManager.getComponentFromEntity<RigidBody>(eid); // Get transform component Transform *transform = entityManager.getComponentFromEntity<Transform>(eid); // Do something with rigid body and transform component } 问题在于,entity1的RigidBody组件可以在其池的索引2处,而entity1的Tranform组件在其池的索引0处(因为某些实体可以具有某些组件,而其他组件不能具有其他组件,并且是因为添加/删除了实体/组件)。 因此,即使组件在内存中是连续的,也会随机读取它们,因此它将有更多的缓存未命中,不是吗? 除非有一种方法可以预取循环中的下一个组件?

1
如何在实体/组件系统中处理物料
我的E / C实现是一种基本的实现,其中实体只是ID,组件是数据,系统根据数据进行操作。现在,我在处理对象材质和渲染时遇到了麻烦。对于简单的objetc,我有一个ModelComponent与绑定的RenderSystem,ModelComponent具有渲染系统使用的顶点缓冲区ID。一个简单的对象MaterialComponent可能具有颜色或镜面反射强度等,但是我希望它具有足够的灵活性,以允许多个渲染过程和一般的“效果”,而这些效果不如的简单变量那么容易MaterialComponent。 为了解决这些问题,我想出了两种解决方案: 1-超通用材料组件 像这样: struct Material : public Component { ShaderData* shader; std::vector<std::pair<std::string, boost::any>> uniforms; [...] }; 在渲染系统中,我将循环并将制服传递给着色器。我想这会很慢,但对于我的目的来说足够快了。 2-另一层抽象,MaterialData 有一个包装特定材料的类,该类可以由任何专门的材料继承,基类将具有类似的东西,void set_shader_constants(ShaderData* d)但是实现取决于每个类,并且MaterialComponent将具有一个指向MaterialData对象的指针。 我不确定我会选择哪种方法,但是这些方法都不涉及多次通过或其他复杂的渲染技术。 关于如何做到这一点的任何想法?

3
将相同组件集的实体分组到线性内存中
我们从基本的系统-组件-实体方法开始。 让我们创建组合(源自长期本文章)仅仅是出于对信息类型的组件。它是在运行时动态完成的,就像我们将组件一个接一个地添加/删除到实体中一样,但是让我们更精确地命名它是因为它仅涉及类型信息。 然后,我们构造为每个实体指定集合的实体。创建实体后,它的组合是不可变的,这意味着我们无法直接对其进行修改,但是仍然可以获得现有实体对本地副本的签名(以及内容),对其进行适当的更改,然后创建一个新实体它的。 现在是关键概念:每创建一个实体,就会将其分配给一个名为assemblage bucket的对象,这意味着具有相同签名的所有实体都将位于同一容器中(例如,在std :: vector中)。 现在,系统只是遍历他们感兴趣的每个环节并完成工作。 这种方法有一些优点: 组件存储在几个(精确地:存储桶数)连续的内存块中-这提高了内存友好性,并且更容易转储整个游戏状态 系统以线性方式处理组件,这意味着改进了缓存一致性-再见字典和随机存储器跳转 创建新实体就像将组合映射到存储桶并将所需组件推回其向量一样容易 删除一个实体就像调用std :: move一样容易,将最后一个元素与删除的元素交换,因为此时顺序并不重要 如果我们有很多具有完全不同的签名的实体,那么缓存一致性的好处就会减少,但是我认为大多数应用程序都不会发生这种情况。 重新分配向量后,指针失效也存在问题-可以通过引入以下结构来解决: struct assemblage_bucket { struct entity_watcher { assemblage_bucket* owner; entity_id real_index_in_vector; }; std::unordered_map<entity_id, std::vector<entity_watcher*>> subscribers; //... }; 因此,只要出于游戏逻辑中的某种原因,我们想要跟踪一个新创建的实体,就在存储桶中注册一个entity_watcher,并且一旦在删除期间必须将该实体std :: move移开,我们便会查找其观察者并进行更新他们real_index_in_vector的新价值。在大多数情况下,这对每个实体删除都仅施加了一个字典查找。 这种方法还有其他缺点吗? 尽管很明显,为什么没有提到解决方案? 编辑:我正在编辑问题以“回答答案”,因为评论不足。 您将失去可插拔组件的动态特性,该特性是为摆脱静态类构造而专门创建的。 我不。也许我没有足够清楚地解释它: auto signature = world.get_signature(entity_id); // this would just return …

3
有关C ++中实体组件系统之间链接的建议
在阅读了有关实体组件系统的一些文档之后,我决定实施我的。到目前为止,我有一个World类,其中包含实体和系统管理器(系统),Entity类(其中包含作为std :: map的组件)以及一些系统。我在世界中将实体作为std :: vector持有。到目前为止没有问题。让我感到困惑的是实体的迭代,我对此一无所知,所以我仍然无法实现这一部分。每个系统都应该保存他们感兴趣的实体的本地列表吗?还是应该仅遍历World类中的实体并创建一个嵌套循环以遍历系统并检查实体是否具有系统感兴趣的组件?我的意思是 : for (entity x : listofentities) { for (system y : listofsystems) { if ((x.componentBitmask & y.bitmask) == y.bitmask) y.update(x, deltatime) } } 但是我认为,在嵌入脚本语言的情况下,位掩码系统会带来一定的灵活性。或者为每个系统使用本地列表将增加类的内存使用量。我非常困惑。

5
为什么在Vector3s中不能使用运算符'> ='?
我正在尝试获得一个矩形,以便在我称为_positionA和的两个位置之间移动_positionB。两者都是类型Vector3。矩形移动得很好。但是,到达时_positionB它不会像应该的那样朝相反的方向移动。 我回到代码中看一看。我得出的结论是,随着对象的移动,if代码中的语句错过了rects位置等于的框架_positionB。如果rects的位置大于或等于, 我决定将代码修改为反向_positionB。我的代码不太长,因此我将在下面显示它: using UnityEngine; using System.Collections; public class Rectangle : MonoBehaviour { private Vector3 _positionA = new Vector3(-0.97f, -4.28f); //Start position private Vector3 _positionB = new Vector3(11.87f, -4.28f); //End position private Transform _rect_tfm; private bool _atPosA = false, _atPosB = false; public Vector2 speed = new Vector2(1f, 0f); private …
9 unity  c#  vector  mathematics  vector  matrix  unity  c#  transformation  java  3d  terrain-rendering  shading  ios  opengl-es  opengl  rendering  optimization  python  scripting  minecraft-modding  modding  pc  3d-meshes  mesh  culling  point-cloud  networking  interpolation  mathematics  game-design  ai  game-mechanics  animation  unreal-4  skeletal-animation  3dsmax  unity  c#  3d  opengl  c++  textures  unity  ide  cocos2d  cocos2d-x-js  unity  c#  mono  il2cpp  c++  game-loop  timer  linux  flash  actionscript-3  java  glsl  c++  vector  entity-component  c++  directx11  windows  visual-studio  libgdx  mouse  unity  c#  architecture  storage  unity  c#  rotation  coordinates  quaternion  vrpn  movement  vector  unreal-4  unity  shaders  unity  gui  text  bug  shooter  3d  animation  rendering  voxels  c++  mmo  multithreading  linux  textures  procedural-generation  terrain-rendering  multiplayer  mmo  game-state  java  android  libgdx  opengl  procedural-generation  unity  gui  3d  animation  tools  geometry-shader  mobile  advertisements  unity  c#  animation  scripting  unity  animation  unityscript  coroutines  unity  shaders  lighting  camera 
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.