C ++组件系统
组件系统使您可以通过一组构建块-组件来实现应用程序的逻辑,并将这些块分配给节点,从而为它们提供附加功能。通过组合这些小块和简单块,您可以创建一个非常复杂的逻辑系统。
逻辑组件集成了一个节点,一个C ++类和一个属性(property),该C ++类包含逻辑实现(要执行的操作),该属性定义了一组要附加的参数。用过的。对于组件和相应的属性,参数列表及其类型相同。
组件为您提供了更多实现逻辑的灵活性,使您能够:
- 控制要执行的代码部分(实现为组件方法),而不要执行
- 控制这些代码部分的执行顺序
- 重复使用一次编写的代码部分,以用于所需的任意数量的对象,而无需进行修改。如果要更改代码,则可以修改一个源(如果谈论内容,则类似于NodeReference)
- 合并要为某些节点执行的代码的某些部分。从许多小的块和简单的块构建一个非常复杂的系统(就像您将使用NodeReference通过许多简单的节点构建一个大型的复杂结构一样)
也可以看看#
- C++组件系统API ,以获取有关通过C++ API管理组件的更多详细信息。
- C++组件系统使用示例,以获取有关使用组件系统实现逻辑的更多详细信息。
- C++ Sample: source/samples/Api/Logics/ComponentSystem
逻辑#
组件的逻辑是通过一组方法来实现的,这些方法由 world 脚本的相应功能调用:
- init()--创建并初始化所有必需的资源。
-
updateAsyncThread()--指定独立于渲染线程的每帧要调用的所有逻辑函数。
此方法没有保护锁,因此,除非您完全确定不会在其他位置修改或删除这些组件,否则不建议在此方法内修改其他组件。 -
updateSyncThread()--在update()之前指定要执行的所有并行逻辑功能. 此方法可用于执行一些消耗大量资源的计算,例如寻路,过程纹理的生成等。
此方法应仅用于调用与当前节点有关的API方法:节点本身,其材质和属性。 - update()--指定要在每帧调用的所有逻辑功能。
- postUpdate()--根据同一帧中更新的节点状态纠正行为。
- updatePhysics()--模拟物理:执行连续操作(根据当前电动机的RPM向前推动汽车,不断模拟风向,执行即时碰撞响应等)。
-
swap()--使用updateAsyncThread()方法的结果进行操作,所有其他方法(线程)已经执行并且处于空闲状态。 此功能之后,仅发生两个动作:
- 所有排队等待删除的对象都将被删除
- 探查器已呈现
- shutdown()--在世界关闭时执行清理。
工作流程#
基本工作流程如下:
- 从ComponentBase类继承一个新的C ++类,该类表示您的组件。此类的模板可在UnigineComponentSystem.h头文件中用作注释。
- 在头文件中,确定并声明此组件将使用的参数列表。所有这些参数及其默认值(如果指定)将存储在专用属性文件中。
- 在某些方法(init(), update(), postUpdate()等)内实现组件逻辑,这些逻辑将由引擎的主循环的相应功能调用。
- 组装项目并运行一次,以生成所有组件的属性。
- 将创建的属性分配给节点以赋予其所需的功能。
每次将在组件系统中注册的属性分配给节点时,都会创建相应组件的实例。当相应的属性替换为另一个属性或从节点的列表中删除该属性时,或者删除该节点时,该实例将被删除。
仅当启用了相应的节点和属性时,某个组件的逻辑才处于活动状态。因此,您可以在运行时启用/禁用每个特定组件的逻辑。
您可以将与不同组件相对应的几个属性分配给单个节点。执行组件逻辑的顺序由为相应方法指定的 order 值确定(如果 order 值相同或未指定,则根据节点的层次结构确定该顺序)。
您也可以为现有属性创建组件。
组件可以与其他组件和节点进行交互。
用法#
例如,您可以使用组件来实现敌人在游戏中追逐玩家的逻辑:不管它们的大小,形状,速度如何,它们都会检查玩家的位置,并尝试寻找更接近的路径他们尽可能快。代码基本上是相同的,只是使用不同的参数(可能是速度,网格或声音),因此您可以将所有这些参数放入属性(可以在以下位置进行更改)随时)和相应组件类的代码(例如,将敌人放置在init()中,并使用update()方法追踪玩家)。
然后,您只需将属性分配给所有敌对对象并设置参数(定义网格物体,声音等),其余部分将由组件系统完成:在引擎的主循环的相应阶段执行您的代码,使用所有敌人的特定参数。如果您决定以后再修改代码,则可以在一个源代码中完成此操作--组件类。
与 Microprofile 工具集成,使您可以监视组件系统的整体性能,并为组件添加性能分析信息。