This page has been translated automatically.
UNIGINE 基础课程
1. 简介
2. 虚拟世界管理
3. 3D模型准备
4. 材质
5. 摄像机和光照系统
7. 制作过场动画与动画序列
8. 准备发布项目
9. 物理系统
10. 优化基础
11. 项目2:第一人称射击游戏
12. PROJECT3: Third-Person Cross-Country Arcade Racing Game
13. PROJECT4: VR Application With Simple Interaction

在编辑器中操作组件

C++ components in Editor are not managed directly, but rather via the associated properties. Unlike C# components that you can create right in UnigineEditor, C++ components are to be added to your C++ project via the IDE first, then compiled, and then registered by the Component System, which generates associated properties to be assigned to nodes in UnigineEditor.在编辑器中使用C++组件时,这些组件不是直接管理的,而是通过关联的属性(property)文件进行控制。与可以直接在UnigineEditor中创建的C#组件不同,C++组件需要先通过IDE添加到你的C++项目中,然后进行编译,最后由组件系统注册并生成关联属性,才能在UnigineEditor中分配给节点。

Workflow
工作流程#

To add a C++ component you should do the following:要为项目添加C++组件,你需要执行以下操作:

1. Open Project in IDE
1. 在IDE中打开项目#

First, open your project in an IDE (Microsoft Visual Studio is recommended) - go to SDK Browser and choose Open Code IDE on your project's card.首先在IDE(推荐使用Microsoft Visual Studio)中打开你的项目:转到SDK Browser,在项目卡片上选择"Open Code IDE"。

2. Add New C++ Component Class
2. 添加新的C++组件类#

In an IDE create a new C++ class (Project → Add Class) and call it MyComponent.在IDE中创建一个新的C++类(Project → Add Class)并将其命名为MyComponent

Make sure it inherits from the ComponentBase class. You can build a whole hierarchy using your own components, by inheriting some components from others in accordance with the OOP principles (we'll review this in detail later).确保它继承自ComponentBase类。你可以根据OOP原则(我们稍后会详细讨论),通过让某些组件继承其他组件来构建完整的层次结构。

Two files*.h and *.cpp will be added to your C++ project.将会向你的C++项目添加两个文件(*.h*.cpp)。

3. Write Component Code
3. 编写组件代码#

Header File (*.H)
头文件(*.H)#

In the header file (MyComponent.h) you should do the following:在头文件(MyComponent.h)中,你需要:

  1. Declare a component class using the following macro:使用以下宏声明组件类

    源代码 (C++)
    COMPONENT_DEFINE(MyComponent, Unigine::ComponentBase);

    Class name defines the name of the property (the corresponding *.prop file is automatically saved in your project's data folder).类名定义了属性(property)的名称(相应的*.prop文件会自动保存在项目的data文件夹中)。

  2. Declare parameters with their default values (if any). The simplest way to declare a parameter is to use the following macro (optional arguments are enclosed in square brackets []):声明参数及其默认值(如果有)。声明参数的最简单方法是使用以下宏(可选参数用方括号[]括起来):

    源代码 (C++)
    PROP_PARAM(param_type, name[, default_value, title, tooltip, group]);

    A set of macros enables you to define multiple types of component parameters to be displayed and adjusted in UnigineEditor. See the the ComponentBase class documentation for the detailed information about supported parameter types and attributes.通过一组宏定义,你可以在UnigineEditor中配置多种组件参数类型并进行调整。完整支持的参数类型及属性说明,请参阅ComponentBase类的官方文档。

    参数类型清单

    The list of available macros includes the following ones to declare complex-type parameters (arrays, structures, and arrays of structures):以下宏可用于声明复合类型参数(数组、结构体及结构体数组):

    源代码 (C++)
    PROP_STRUCT(type, name);
    PROP_ARRAY(type, name);
    PROP_ARRAY_STRUCT(type, name);
  3. Declare which methods you are going to use to implement component's logic, and during which stages of the execution sequence to call them:声明你将使用哪些方法来实现组件逻辑,以及在执行序列的哪些阶段调用它们:

    源代码 (C++)
    public:
    	COMPONENT_INIT(my_init);
    	COMPONENT_UPDATE(my_update);
    	COMPONENT_SHUTDOWN(my_shutdown);
    // ...
    protected:
    	void my_init();
    	void my_update();
    	void my_shutdown();
  4. Declare all necessary auxiliary parameters and functions.声明所有必要的辅助参数和函数

Implementation File (*.CPP)
实现文件(*.CPP)#

In the implementation file (MyComponent.cpp) you should do the following:在实现文件(MyComponent.cpp)中,你需要:

  1. Register the component class in the Component System using the following macro:使用以下宏在组件系统中注册组件类

    源代码 (C++)
    REGISTER_COMPONENT(MyComponent);
  2. Implement your component's logic in the methods that you've declared in the header file.在头文件中声明的方法中实现组件的逻辑

We'll make a simple component that will rotate a node to which it is assigned every frame at a certain angle. Summarizing all the things above we can make our component look like it is shown below. You can copy the code, paste it to the corresponding files in your project and save them in your IDE.我们将创建一个简单的组件,该组件每帧以特定角度旋转它被分配到的节点。总结以上所有内容,我们可以使我们的组件如下所示。你可以复制代码,将其粘贴到项目中的相应文件,然后在IDE中保存它们。

MyComponent.h (C++)
#pragma once
// 包含组件系统头文件
#include <UnigineComponentSystem.h>
class MyComponent :
	public Unigine::ComponentBase
{
	// 声明构造函数/析构函数,并定义组件关联属性名称
	// 首次运行应用后,将在项目data文件夹生成包含以下参数的MyComponent.prop文件
	COMPONENT_DEFINE(MyComponent, Unigine::ComponentBase);

	// 声明组件参数并设置初始值
	PROP_PARAM(Float, angle, 10.0f, "Angle", "Node rotation angle", 0, "max=360;min=0");

	// 注册将在世界逻辑各阶段调用的方法(方法在protected区声明)
	COMPONENT_UPDATE(update);

protected:
	// 声明将在世界逻辑各阶段调用的方法
	void update();
};
MyComponent.cpp (C++)
#include "MyComponent.h"
// 在组件系统中注册MyComponent组件
REGISTER_COMPONENT(MyComponent);
using namespace Unigine;
using namespace Math;

// 每帧调用的方法
void MyComponent::update()
{
	// 根据组件参数(Angle)设置的值,使物体每帧绕Z轴旋转
	node->rotate(0.0f, 0.0f, angle);
}

4. Compile And Run To Generate Property
4. 编译运行生成属性文件#

Don't forget to set the appropriate platform and configuration settings for your project before compiling your code in Visual Studio.Visual Studio中编译代码前,请确保为项目设置正确的平台和配置参数。

Build and run your application by hitting Ctrl + F5 to make the Component System register the component and generate an associated property with the corresponding set of parameters (according to your component's class declaration) to be used to assign the component to nodes. Close the application after running it and switch to UnigineEditor.Ctrl + F5构建并运行应用,使组件系统注册组件并生成关联属性(property)文件(根据组件类声明生成对应参数集)。运行后关闭应用,返回UnigineEditor。

5. Assign Component To Nodes In Editor
5. 在编辑器中为节点分配组件#

After successful registration all available properties associated with your C++ components are displayed in the Properties window as children of the basic node_base property.成功注册后,所有可用C++组件属性将作为node_base属性的子项显示在Properties(属性)窗口中。

The component is ready, but now it must be assigned to some node, otherwise its code won't be executed. Decide which object you want to rotate (e.g. Material Ball), drag the property (MyComponent.cpp) from the Properties hierarchy and drop onto this object (you can drop it on the object directly in the viewport or on the node in the World Nodes window).组件已就绪,但现在必须将其分配给某个节点,否则其代码不会被执行。选择需要旋转的对象(如Material Ball),将属性文件(MyComponent.cpp)从Properties(属性)层级拖放至目标对象(可直接拖到视口对象或World Nodes(世界节点)窗口中的节点上)。

In the Parameters window set the desired Angle value with a slider and save the world by hitting Ctrl + S.在参数窗口中使用滑块设置角度值(Angle),按Ctrl + S保存场景。

The component can be assigned to a node via code as well:组件同样可以通过代码方式分配给节点:

源代码 (C++)
// 方式一:
ComponentSystem::get()->addComponent<MyComponent>(node);
// 方式二(通过添加组件关联的属性):
node->addProperty("mycomponent_prop_name");

Now, we're ready to launch our application via the SDK Browser by selecting the project on the Projects tab and clicking Run. But before doing so let's make sure, that appropriate Customize Run Options (Debug version in our case) are selected, by clicking an ellipsis under the Run button (check Debug and Remember then click Run).现在,我们已准备通过SDK Browser运行应用:在"Projects"(项目)选项卡选中项目后点击Run("运行"。但在此之前,请点击运行按钮下方的省略号图标,确保已选择正确的"Customize Run Options"(自定义运行选项)(本例选择Debug版本),勾选"Debug"并"Remember"(记住)设置后点击"Run"(运行)。

Check if the object rotates as intended!验证对象是否按预期旋转!

Hierarchy and Inheritance, Overriding Parameters and Overloading Methods
层级与继承,参数重写和方法重载#

Suppose you have a component that implements a certain functionality, and you need a certain number of subcomponents that have exactly the same functionality but different parameter values. This is a common situation when implementing quality presets or control configurations. Simply inherit a property from the base component in the Editor for each preset and configure the required parameter values. You can then assign these inherited properties to nodes, thus attaching the logic of the base component with parameter values taken from the inherited properties. No unnecessary copying, no redundant code.假设你有一个实现特定功能的组件,现在需要创建多个具有完全相同功能但参数值不同的子组件。这在实现质量预设或控制配置时是常见情况。只需在编辑器中对每个预设从基础组件继承一个属性,并配置所需的参数值即可。之后你可以将这些继承的属性分配给节点,从而附加基础组件的逻辑,同时使用继承属性中的参数值。无需不必要的复制,也没有冗余代码。

In addition to overriding parameter values, you can also extend the functionality of base components in child components. This is done in accordance with the OOP concept by inheriting the child component class from the base component class, for example:除了重写参数值外,你还可以在子组件中扩展基础组件的功能。这是按照OOP概念,通过让子组件类继承基础组件类来实现的,例如:

源代码 (C++)
// Interactable类继承自基础ComponentBase类
class Interactable : public Unigine::ComponentBase
{
public:
	COMPONENT_DEFINE(Interactable, ComponentBase);

	// 参数
	PROP_PARAM(String, tooltip, "Info about the object");

	// 虚方法:子类需实现的交互动作
	virtual void action(int num = 0) {};
};

// ------------------------------------------------------------------
// Toggle类继承自Interactable类
class Toggle : public Interactable
{
public:
	COMPONENT_DEFINE(Toggle, Interactable);

	// 新增参数
	PROP_PARAM(Node, controlNode, nullptr);

	// ...

	// 重写父类的action方法
	void action(int num = 0)
	{
		if (num != 0)
			return;
		Unigine::Log::message("Toggle action for: %s \n ", node->getName());
		// ...
	}

	// 扩展的新功能方法
	void someNewMethod()
	{
		//...
	}

	// ...
};

We'll review more examples a bit later.稍后我们将查看更多示例。

Debugging Components
组件调试#

The Microsoft Visual Studio environment is known for its excellent debugging tools. You can test the source code of C++ components while your application is running, whether the application is launched via the SDK Browser or created and running from the IDE.Microsoft Visual Studio 环境以其卓越的调试工具而闻名。你可以在应用程序运行时测试 C++ 组件的源代码,无论该应用程序是通过 SDK Browser 启动(Attach)还是从 IDE 创建并运行的。

Debugging in IDE
在集成开发环境中调试#

To compile all your components, build the application, and debug it by running it directly from the IDE, select Debug → Start Debugging (or press F5):要编译所有组件、构建应用程序并直接从IDE运行调试,请选择Debug → Start Debugging(调试 → 开始调试)(或按F5键):

Now you can add the necessary breakpoints and just press F5 to start the debugging process.现在你可以添加必要的断点,只需按F5即可开始调试过程。

At startup, the application will run with the world set for your project in SDK Browser at creation. If the default world is not set, you will see a black screen after launching the app. In this case, you can open the console (press "~" on the keyboard) and load the desired world using the world_load <world_name> console command.应用程序启动时将加载SDK Browser创建项目时设定的默认场景。若未设置默认场景,启动后将显示黑屏。此时可打开控制台(按键盘"~"键),通过world_load <场景名称> 控制台命令加载目标场景。

Attaching to Running Application
附加至运行中的应用程序#

You can also connect Visual Studio debugger to an instance of your application that is already running. The most common case is launching it via the SDK Browser. Just add necessary breakpoints and select Debug → Attach To Process from the main menu.你也可以将Visual Studio调试器连接到已运行的应用程序实例。最常见的情况是通过SDK Browser启动应用程序。只需添加必要的断点,然后从主菜单中选择Debug → Attach To Process(调试 → 附加到进程)。

Type your project's name in the search field in the Available processes section to find the process you need. Select it in the list and click Attach在"Available processes"(可用进程)部分的搜索栏中输入项目名称以查找所需进程。从列表中选择该进程,然后单击Attach(附加)。

Setting Breakpoints
断点设置#

Breakpoints are used to pause your application by stopping execution of your code and giving you a chance to inspect and analyze your program's operation. You can check values of variables, and move step-by-step through your code.断点用于通过停止代码执行来暂停应用程序,让你有机会检查和分析程序运行情况。你可以检查变量的值,并逐步执行代码。

To set up a breakpoint put the cursor to the desired line of your code and press F9 or use the menu.设置断点时,将光标置于目标代码行后按F9键或使用右键菜单操作。

本页面上的信息适用于 UNIGINE 2.20 SDK.

最新更新: 2025-06-09
Build: ()