C ++组件系统
Component System enables you to implement your application’s logic via a set of building blocks - components, and assign these blocks to nodes, giving them additional functionality. By combining these small and simple blocks you can create a very sophisticated logic system. 组件系统使您可以通过一组构建块-组件来实现应用程序的逻辑,并将这些块分配给节点,从而为它们提供附加功能。通过组合这些小块和简单块,您可以创建一个非常复杂的逻辑系统。
A logic component integrates a node, a C++ class, containing logic implementation (actions to be performed), and a property, defining a set of additional parameters to be used. The list of parameters as well as their types are the same for both, the component and the corresponding property.逻辑组件集成了一个 node ,一个C ++类和一个 property ,该C ++类包含逻辑实现(要执行的操作),该属性定义了一组要附加的参数。用过的。对于组件和相应的属性,参数列表及其类型相同。
Components give you more flexibility in implementing your logic, enabling you to:组件为您提供了更多实现逻辑的灵活性,使您能够:
- Control which parts of code (implemented as component methods) are to be executed, and which of them are not.控制要执行的代码部分(实现为组件方法),而不要执行。
- Control execution order of these parts of code.控制这些代码部分的执行顺序。
- Repeatedly use parts of code, written once, for as many objects as you need, with no modifications required. If you want to change your code, you modify a single source (similar to NodeReferences, if we talk about content).重复使用一次编写的代码部分,以用于所需的任意数量的对象,而无需进行修改。如果要更改代码,则可以修改一个源(如果谈论内容,则类似于NodeReferences)。
- Combine certain parts of code to be executed for certain nodes. Build a very sophisticated system from numerous small and simple blocks (like you would use a NodeReference to build a large complex structure using many simple nodes).合并要为某些节点执行的代码的某些部分。从许多小的块和简单的块构建一个非常复杂的系统(就像您将使用NodeReference通过许多简单的节点构建一个大型的复杂结构一样)。
See Also也可以看看#
- C++ Component System API for more details on managing components via C++ API. C ++组件系统API ,以获取有关通过C ++ API管理组件的更多详细信息。
- C++ Component System Usage Example for more details on implementing logic using the Component System. C ++组件系统使用示例,以获取有关使用组件系统实现逻辑的更多详细信息。
- C++ Sample: source/samples/Api/Logics/ComponentSystem C++ Sample: source/samples/Api/Logics/ComponentSystem
Logic逻辑#
Logic of components is implemented via a set of methods, that are called by the corresponding functions of the world script:组件的逻辑是通过一组方法来实现的,这些方法由 world脚本的相应功能调用:
- init() — create and initialize all necessary resources init() —创建并初始化所有必需的资源
- updateAsyncThread() — 指定独立于渲染线程的每帧要调用的所有逻辑函数。 This method does not have protection locks, so it is not recommended to modify other components inside this method, unless you are absolutely sure, that these components won't be modified or removed elsewhere.此方法没有保护锁,因此,除非您完全确定不会在其他位置修改或删除这些组件,否则不建议在此方法内修改其他组件。
- updateSyncThread() — 在update()之前指定要执行的所有并行逻辑功能. 此方法可用于执行一些消耗大量资源的计算,例如寻路,过程纹理的生成等。
This method should be used to call only the API methods related to the current node: the node itself, its materials and properties.此方法应仅用于调用与当前节点有关的API方法:节点本身,其材料和属性。
- update() — specify all logic functions you want to be called every frame update() —指定要在每帧调用的所有逻辑功能
- postUpdate() — correct behavior according to the updated node states in the same frame postUpdate() —根据同一帧中更新的节点状态纠正行为
- updatePhysics() — simulate physics: perform continuous operations (pushing a car forward depending on current motor's RPM, simulating a wind blowing constantly, perform immediate collision response, etc.). updatePhysics() —模拟物理:执行连续操作(根据当前电动机的RPM向前推动汽车,不断模拟风向,执行即时碰撞响应等)。
- swap() — 使用updateAsyncThread()方法的结果进行操作 — 所有其他方法(线程)已经执行并且处于空闲状态。 此功能之后,仅发生两个动作:
- All objects that are queued for deletion are deleted.所有排队等待删除的对象都将被删除。
- Profiler is rendered. 探查器已呈现。
- shutdown() — perform cleanup on world shutdown shutdown() —在世界关闭时执行清理
Workflow工作流程#
The basic workflow is as follows:基本工作流程如下:
- Inherit a new C++ class representing your component from the ComponentBase class. The template of this class is available in the UnigineComponentSystem.h header as a comment.从ComponentBase类继承一个新的C ++类,该类表示您的组件。此类的模板可在UnigineComponentSystem.h标头中用作注释。
- In the header file determine and declare the list of parameters to be used by this component. All of these parameters with their default values (if specified) will be stored in a dedicated property file.在头文件中,确定并声明此组件将使用的参数列表。所有这些参数及其默认值(如果指定)将存储在专用属性文件中。
- Implement component logic inside the certain methods (init(), update(), postUpdate(), etc.), that will be called by the corresponding functions of the Engine's main loop.在某些方法(init(), update(), postUpdate()等)内实现组件逻辑,这些逻辑将由引擎的 主循环的相应功能调用。
- Assemble the project and run it once to have the properties for all components generated.组装项目并运行一次,以生成所有组件的属性。
- Assign the created property to a node to give it the desired functionality.将创建的属性分配给节点以赋予其所需的功能。
Each time a property registered in the Component System is assigned to a node, an instance of the corresponding component is created. This instance will be deleted when the corresponding property is replaced with another one or removed from the node’s list, or when the node is deleted.每次将在组件系统中注册的属性分配给节点时,都会创建相应组件的实例。当相应的属性替换为另一个属性或从节点的列表中删除该属性时,或者删除该节点时,该实例将被删除。
The logic of a certain component is active only when the corresponding node and property are enabled. Thus, you can enable/disable logic of each particular component at run time when necessary.仅当启用了相应的节点和属性时,某个组件的逻辑才处于活动状态。因此,您可以在运行时启用/禁用每个特定组件的逻辑。
You can assign several properties corresponding to different components to a single node. The sequence, in which the logic of components is executed, is determined by the order value specified for the corresponding methods (if order values are the same or not specified, the sequence is determined in accordance with the hierarchy of nodes).您可以将与不同组件相对应的几个属性分配给单个节点。执行组件逻辑的顺序由为相应方法指定的order值确定(如果order值相同或未指定,则根据节点的层次结构确定该顺序)。
You can also create components for existing properties.您也可以为现有属性创建组件。
Components can interact with other components and nodes.组件可以与其他组件和节点进行交互。
Usage用法#
As an example, you can use components to implement logic of enemies chasing the player in your game: regardless of their size, shape, speed, all of them will check player's position, and try to find a path to move closer to it as fast as they can. The code will be basically the same, it'll just use different parameters (speed, mesh, or sounds maybe), so you can put all these parameters to a property (to be able to change them at any time) and the code to the corresponding component class (e.g. place enemies in the world in the init() and chase the player in the update() method).例如,您可以使用组件来实现敌人在游戏中追逐玩家的逻辑:不管它们的大小,形状,速度如何,它们都会检查玩家的位置,并尝试寻找更接近的路径他们尽可能快。代码基本上是相同的,只是使用不同的参数(可能是速度,网格或声音),因此您可以将所有这些参数放入 property (可以在以下位置进行更改)随时)和相应组件类的代码(例如,将敌人放置在init()中,并使用update()方法追踪玩家)。
Then you should simply assign the property to all enemy objects and set up parameters (define meshes, sounds, etc.) The Component System will do the rest: execute your code at the corresponding stages of the Engine's main loop for all enemy objects using their specific parameters. Should you decide to modify your code later, you can do that in a single source - component class.然后,您只需将属性分配给所有敌对对象并设置参数(定义网格物体,声音等),其余部分将由Component System完成:在引擎的 main循环的相应阶段执行代码使用所有敌人的特定参数。如果您决定以后再修改代码,则可以在一个源代码中完成此操作-组件类。
Integration with the Microprofile tool, enables you to monitor overall performance of the Component System, as well as to add profiling information for your components.与 Microprofile 工具集成,使您可以监视组件系统的整体性能,并为组件添加性能分析信息。