Articles of 的基于组件的

面向数据的devise和Component Sytem交叉引用

假设我们正在讨论用C ++编写的游戏(引擎)。 这更像是一个devise问题,但我找不到任何合适的描述。 组件系统 组件系统说世界上的一个实体是由其组件定义的。 这个系统是灵活的,模块化和非常强大的。 我已经使用Unity(很多),我喜欢它的概念。 这也解决了传统的类层次问题。 示例组件: StaticTransform :位置,旋转,缩放 – StaticTransform可以是另一个StaticTransform的子节点(当然也可以是父节点)(它描述了场景中的实体层次结构) 刚体/变换 :位置,旋转,力等 – 我可以使用StaticTransform数据,但是我想分离这些概念。 这就是为什么我有位置和旋转(但不是比例)数据。 刚体不能是另一个对象的子体,但可以是StaticTransform的父体。 MeshRenderer :LocalBounds,WorldBounds,Mesh,Material – 此组件用于生成绘制调用以使用特定材质渲染网格。 AudioSource :AudioData – 一个简单的audio源,可以是世界空间(使用其中一个变换)或全局(在这种情况下,变换组件是无关紧要的) AudioListener :只允许一个AudioListener。 大多数情况下,它被添加到玩家的实体。 它使用变换的数据。 相机 :FoV,剪切平面等 – 当然,从这个角度来看,Camera可以用来渲染网格。 允许多台摄像机。 数据导向devise(DoD) 国防部的关键概念是专注于数据和数据访问,而不是代码。 还有一些额外的“规则”,如“有一个,有很多”。 大多数情况下,这意味着数据本身以caching友好的方式存储:与线性访问(也就是逐个迭代数组)的连续内存。 在“组件系统世界”中,组件本身不存在,但相应的系统存储和管理数据。 在这样的系统中,原始或托管的指针被遗忘,而是使用id和/或句柄(带有附加信息的特殊id)。 大多数情况下,使用特殊的entityId – > componentId映射来匹配实体和组件。 这样组件数据可以被打包(移动到数组中),所以iretation是快速的(caching友好的)。 理论上这个工作真的很好。 博客文章和其他讨论显示了如何用一个“组件”来做到这一点。 然而,我找不到任何交叉参考问题的好办法。 交叉引用问题 使用上面描述的示例组件:MeshRenderer依赖于(包括静态和dynamic)Transform组件,因为需要Worldmatrix来渲染/剔除网格。 AudioSource,Camera和AudioListener也依赖于Transform组件。 可以使用变换的父子关系将实体排列成一个层次结构。 当用户更新根对象的变换时,每个子变换也必须更新。 […]

基于组件的基于多态的实体系统:OpenGL不渲染

我想能够从不同的组件集创建实体。 我想调用Entity entity(new StaticObject(modelpath, position)); 我有一个EntityTypes标题: struct EntityType { public: std::vector<Component*> components; }; struct StaticObject :public EntityType { StaticObject(std::string meshPath, glm::vec3 Position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 Orientation = glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f)); Mesh mesh; Space space; }; 在构造函数中,我初始化成员Mesh和Space ,并将它们的地址推送到std::vector<Component*> components;的后面std::vector<Component*> components; 然后,我的实体将指针指向StaticObjecttypes(带有成员向量组件),并将指向组件的指针连同其唯一的实体ID一起插入到多图中( std::multimap<unsigned int, Component*> entityComponents contains all component在我的游戏中的实例,我可以使用实体ID访问它们)。 […]

将c ++模板化函数绑定到lua

我已经开始使用Lua作为我的游戏引擎的脚本语言。 它完美的工作,如input,audio等。但是,我现在试图绑定我的实体组件系统function,大量使用模板。 例如,在c ++中获取一个实体的组件看起来像这样: uint32 entity = 1; Transform &transform = registry.get<Transform>(entity); 并添加一个组件到一个实体: registry.add<Velocity>(entity, 0.0f, 0.0f); 从我可以告诉,Lua无法处理模板函数 – 我将不得不为每个组件绑定一个新的函数,例如getTransformComponent(entity) 。 这显然不是很好,成为最终用户的巨大痛苦。 我查了一下,找不到对我的问题有特别帮助的东西。 我看到一些人提出像getComponent("Transform")但我不明白这是如何在C ++中实现的,因为我的组件是POD ,没有基础的“组件”类?

如何启用和禁用游戏对象上的脚本?

这个昨天简短的工作,我相信我做了一些搞砸了。 我input的所有内容都是正确的。 因此,它必须是代码。 我想换玩家。 虽然红色立方体的脚本启用,并可以移动脚本下移动,我希望蓝色立方体移动脚本被禁用,反对。 你能给我一些见解,我做错了什么? 谢谢,麻烦您了!! using UnityEngine; using System.Collections; public class PlayerMovementScript : MonoBehaviour { public float speed = 2f; public float height = 2f; public Component playerMovement; public GameObject redCube; public GameObject blueCube; void Start() { var bc = blueCube.GetComponent<PlayerMovementScript>(); bc.enabled = !bc.enabled; } // Update is called once per frame void […]

search地图的次数更less

…或者更好,不需要search地图。 我正在寻找如何优化我的代码或devise更改的建议。 在我的基于组件的实体系统中,实体由属性和行为对象组成。 行为对象只存储在一个std :: vector中; 他们没有问题,我只是打电话给他们的更新function。 属性,我存储在<std::string, Attribute>的地图中,它们表示行为(行为从不直接交互)之间的通信path。 行为需要一个属性时,它会search其实体的地图。 对于行为来说,每秒钟访问这些信息有点困难,比如渲染行为(在屏幕上绘制实体)。 渲染需要读取“位置”,“方向”和其他一些东西,而且每秒需要执行几次。 我该如何解决这个问题? 还应该注意的是,基类“实体”,“属性”和“行为”是用C ++编写的,但是它们是用Python编写的。

SceneManagers作为系统中的系统还是作为系统使用的核心类?

看来实体系统在这里非常受欢迎。 其他用户发布的链接使我相信这样的系统的力量,我决定尝试一下。 (那么,我的原始代码越来越杂乱) 在我的项目中,我最初有一个SceneManager类,它维护着组织场景所需的逻辑和结构(QuadTree,2D游戏)。 在渲染之前,我调用selectRect()并传递相机的x,y和屏幕的宽度和高度,然后获得一个最小化的列表,其中只包含从后到前排列的可见实体。 现在系统,最初在我的第一次尝试我的渲染系统需要添加它应该处理的所有实体。 这听起来像是正确的做法,但我意识到这是不高效的。 尝试优化它我在Renderer系统内部重用了SceneManager类,但是后来我意识到我需要在其他系统中使用selectRect()方法(主要是AI),并使SceneManager再次全局可访问。 目前,我将SceneManager转换为一个系统,并以下面的接口(只有相关的方法)结束: /// Base system interface class System { public: virtual void tick (double delta_time) = 0; // (methods to add and remove entities) }; typedef std::vector<Entity*> EntitiesVector; /// Specialized system interface to allow query the scene class SceneManager: public System { public: virtual EntitiesVector& cull () = […]

你将如何为这样的实体devise组件?

这不是关于如何实现基于组件的系统的问题。 我有我自己的系统执行和工作相当好,只是不能找出一个好的方法来拆分一些实体,以适应基于组件的范例。 这个实体相当简单,它可以走路,跳跃和射击。 它可以进入一些状态,如“冻结”,避免玩家的移动。 它有其他限制,如不能做双跳。 在我目前的系统中,我有一个input管理器,它有一个目标实体,它接收映射到具有语义的动作的事件。 我的意思是,我的实体不知道“D”键或“鼠标左键单击”,它知道Up,Down,Button1等等。 现在的问题是,当用户按下例如SPACE时,目标实体用左动作通知并且所有的组件都被通知,但是例如运动组件如何知道该实体处于“冻结状态”并且它不应该“不是在运动吗? 你会抛出所有这些属性到一个实体属性组件,并让所有其他组件检查他们? 你是否会将实体分割成一个颗粒状的级别,以便为每个财产创建一个组件? 在这种情况下,我们可以有一个具有“可以被冻结”属性的组件,当它接收到一个冰投影(它将接收到一个冲突消息)的碰撞时,它可以设置主要实体状态(我将它放入大脑的组成部分)冻结。 你能建议你如何处理这个任务吗? 这个问题可以重写为:如何考虑到实体的限制,从input系统执行操作。 提前致谢。

实体组件系统游戏引擎更多的面向数据的devise方法

我正在创建我的第一个C ++游戏引擎项目(用于学习目的),并且在其中尝试使用一些面向数据的devise原则来实现一个实体/组件系统,同时还没有完全放弃我的面向对象的思维方式。 我只有数据组件结构: (例) Position.h struct Position { Vector3D position{ 0.0f, 0.0f, 0.0f }; }; 它们存储在我的SceneManager类中的数组中: SceneManager.h class SceneManager { //Some other code…. private: //So only systems have access to component arrays friend class BGraphics::RenderSystem; friend class BInput::InputSystem; friend class BPhysics::MovementSystem; friend class BPhysics::CollisionSystem; friend class BAudio::AudioSystem; //Component arrays. Each index of the arrays represents […]

实体 – 组件 – 系统数据存储devise

我正在研究一个ECS,我已经阅读了很多关于它的文章。 大多数这些文章都在谈论一个简单的案例(连续存储数据,读一个单一的循环)。 然而,现实世界更为复杂:一个系统读取多个组件,而这些组件必须快速读取。 所以我在想一个新的数据存储模型,但是在我开始实现它之前,我想知道你在想什么:我不确定这个devise是否能解决任何(未来)的性能问题(我是考虑高速caching一致性,预取等优化)。 所以基本是一样的: 每个实体都是一个句柄(id +版本号)。 每个组件都是一个(n理想的小)POD。 每个系统负责处理一组组件。 每篇文章中的第一个想法是将组件数据存储在一个数组中(每种types),并使用快速查找映射(例如hash_map)作为entity_id-> component_id关系。 例如。 位置组件包看起来像这样: component data: [pos_0][pos_1]…[pos_n] entity->component map: [entity_0 -> 1][entity_2 -> 0]…[entity_m -> n] 如果系统正在线性读取单一types的组件,这将会很有效。 如果一个系统也想读另一个组件,它将至less生成两个额外的caching未命中: 一个用于entity_id-> component_id查找(从实体中查找其他组件) 一个用于实际的组件数据 所以我的想法是,而不是分离我可以创建组的组件。 每个组都具有与之前相同的行为(连续排列数据,存储entity_id-> component_id映射以便快速查找组件),但数据存储多个组件数据。 重点在于组件数据以与其他组件相同的顺序存储,所以如果系统想要读取,例如。 位置+速度组件设置它可以在数组上线性迭代。 每个组件types都有一个偏移量来指示它在大数组上的起始位置。 所以Position + Velocity组看起来像这样: component data: [pos_0][pos_1]…[pos_n][… some space …][vel_0][vel_1]…[vel_n]… and so on entity->component map: [entity_0 -> 1][entity_2 -> 0]…[entity_m […]

基于实体组件系统的引擎

注意:我使用Javascript进行编程,但大部分应该是语言不可知的。 我正在考虑将我的引擎转换为基于ECS的引擎。 我得到了基本的想法( 注意:这是错误的,请参阅我的答案 ): 实体是游戏对象。 组件是可以“粘”到实体的function位( reactToInput() )或状态( position )。 系统有一个他们管理和更新的实体列表。 但是,我不太确定我是否得到了实施和一些细节… 问题: 一个系统可以在不同types的实体上运行吗? 我通常在我的引擎中给出一个名为Scene的类的例子,现在它也将用于这个目的。 一个场景是所有对象的容器,可以被渲染,更新,影响渲染(灯光),甚至可能在将来甚至是2DSoundEmitter对象。 它有一个高级接口,所以用户不需要担心他的scene.add()对象的types,以及所有这些东西。 我意识到Scene可能是一个系统。 它接受实体,存储它们,然后它可以调用它们的更新方法,甚至可以做一些状态改变。 但是,有一个问题:正如我上面所描述的, Scene可以被送入不同types的对象! 我应该做些什么,比如说一个场景中既有可渲染对象(“drawable”) 又有灯光的情况? 我应该在交互之前进行types检查吗? 或者,我应该在更低的层次上解决这个问题:创建一个可以添加到任何对象的LightSource组件,而光源只是一个具有LightSource和Position组件的实体。 这可以接受吗? 另外,仍然使用传统的inheritance和传统类是一个很好的做法吗? 例如,我只是不知道我的Renderer会是什么! 它不是一个系统,因为它的唯一function是摄取相机和场景,渲染所有内容并应用效果(如阴影)。 它还管理的背景下,游戏的宽度和高度,使翻译…但它仍然不是一个系统! 编辑:你可以链接你在ECS上find的资源吗? 我很难find好的。