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

常见案例解决方案

In this section of our course we are going to review some examples of solving typical problems and use the gained experience to implement various functionality in our Archviz project.在本节课程中,我们将通过几个典型案例的解决方案,并将这些经验应用到我们的建筑可视化项目中。

To warm up, let's practice organizing the class hierarchy in components. In addition to boring static objects, the project will contain the interactive ones — those you can do something with (for example, turn on/off, change the material, delete, etc.). Let's create a base component Interactable that will act as a base class for such types of objects. Add a virtual method action(num) which will be overloaded by child classes (num here stands for the action number, since we want to be able to perform more than one action with some objects). In addition, the base class implements a method that displays a text hint about the type of the interactive object and its functionality using the Visualizer class (this class is used to render all sorts of additional information that can be useful for debugging and other purposes).首先,让我们练习组件类的层级组织。除了静态对象外,项目中还将包含可交互对象(如开关控制、材质变更、删除等功能)。我们将创建一个基础组件Interactable作为这些交互对象的基类,其中包含一个虚方法action(num)供子类重写(num表示动作编号,用于支持多动作交互)。基类还实现了通过Visualizer类显示对象功能提示的方法(Visualizer类常用于调试信息的可视化呈现)。

Open your project in an IDE - go to SDK Browser and choose Open Code IDE on your project's card.在集成开发环境(IDE)中打开你的项目:请前往SDK浏览器,在Projects(项目)卡片上选择Open Code IDE(打开代码的IDE)。

In an IDE create a new C++ class (*.h and *.cpp files) and call it Interactable. Make sure it inherits from the Unigine::ComponentBase class.在IDE中创建一个新的C++类(包含*.h*.cpp文件),命名为Interactable。请确保该类继承自Unigine::ComponentBase基类。

Copy the code below and paste it to the corresponding files in your project and save them in your IDE.将以下代码复制并粘贴到你项目的对应文件中,然后在IDE中保存:

注意
It is recommended to use Visual Studio as a default IDE.推荐使用Visual Studio作为默认集成开发环境。
Interactable.h (C++)
#include <UnigineComponentSystem.h>

class Interactable : public Unigine::ComponentBase
{
public:
	// 声明类的构造函数/析构函数,并定义与组件关联的属性(property)名称
	// 首次运行应用后,将在项目data目录生成包含以下参数的Interactable.prop文件
	COMPONENT_DEFINE(Interactable, ComponentBase);

	// 声明组件参数并设置默认值
	PROP_PARAM(String, tooltip, "对象信息");		// 交互对象的说明信息

	// 实现指定编号操作的虚方法
	virtual void action(int num = 0) {};
	// 使用Visualizer显示提示信息的方法
	void displayInfo();
};
Interactable.cpp (C++)
#include "Interactable.h"
#include <UnigineVisualizer.h>

// 注册Interactable组件
REGISTER_COMPONENT(Interactable);
using namespace Unigine;
using namespace Math;

// 显示交互对象类型及其功能提示的方法
void Interactable::displayInfo()
{
	// 使用Visualizer显示提示信息
	Visualizer::renderMessage2D(vec3(0.0f, 1.0f, 0.0f),
		vec3(1.0f, 0.1f, 0.0f),
		String::format(" >>  %s : %s\n\n", node->getName(), tooltip.get()),
		vec4_green, 1, 18);
}

Now, let's inherit the Toggle component (as an action to enable/disable the controlled node) from the component described above.接下来创建继承自Interactable的Toggle组件(用于控制节点开关状态)。

Similarly, in your IDE add a new class (Project → Add Class), call it Toggle, and type Interactable in the Base class field instead of the standard ComponentBase class.同样地,在你的 IDE 中添加一个新类(Project → Add Class),将其命名为 Toggle,并在基类字段中输入 Interactable 以替代标准的 ComponentBase 类。

Copy the code below, paste it to the corresponding files in your project and save them in your IDE.将以下代码复制到你项目中的相应文件并保存。

Toggle.h (C++)
#pragma once
#include <UnigineComponentSystem.h>
#include "Interactable.h"

class Toggle :
	public Interactable
{
public:
	// 声明类的构造函数和析构函数,并定义与组件关联的属性(property)名称
	// 首次运行应用程序后,将在项目的 data 文件夹中生成包含以下所有参数的 Toggle.prop 文件
	COMPONENT_DEFINE(Toggle, Interactable);

	PROP_PARAM(Node, controlNode, nullptr);			// 受控节点
	
	// 注册在世界逻辑初始化阶段调用的方法(方法在下面的 protected 部分声明)
	COMPONENT_INIT(init);

	// 重载实现受控节点切换的 action 方法
	void action(int num = 0);

protected:
	// 声明组件初始化方法
	void init();
};
Toggle.cpp (C++)
#include "Toggle.h"
#include <UnigineLog.h>

// 注册 Toggle 组件
REGISTER_COMPONENT(Toggle);

using namespace Unigine;
using namespace Math;

// 组件初始化方法
void Toggle::init()
{
	// 如果没有分配受控节点,则将相应警告打印到控制台
	if (!controlNode)
		Log::message("节点 %s 未分配受控节点!\n", node->getName());
	else
		// 设置当光标悬停在对象上时将显示的提示文本
		tooltip = Unigine::String::format("右键点击可开关受控节点 (%s) 。", controlNode->getName());
}

// 重载实现受控节点切换的 action 方法
void Toggle::action(int num)
{
	// 对于此组件,除零以外的操作索引无效,因此被忽略
	if (num != 0)
		return;

	// 检查是否分配了受控节点
	if (controlNode)
	{
		// 切换受控节点的状态
		controlNode->setEnabled(!controlNode->isEnabled());
	}
}

Let's save our files and then build and run our application by hitting Ctrl + F5 to make the Component System generate a property to be used to assign our component to nodes. Close the application after running it and switch to UnigineEditor.让我们保存文件,然后按下 Ctrl + F5 构建并运行我们的应用程序,这样组件系统就会生成一个属性文件,用于将我们的组件分配给节点。运行应用程序后将其关闭,然后切换到 UnigineEditor。

Now let's assign this component to the light switches in the room, and associate them with the corresponding light sources:现在让我们将此组件分配给房间中的电灯开关,并将它们与相应的光源关联:

Assign the Toggle component to the socket_2_switch_lod_1 node of the left bedside switch, and drag the LightOmni_0 node into the Control Node field.Toggle组件分配给左侧床头开关的socket_2_switch_lod_1节点,并将LightOmni_0节点拖到Control Node字段中。

Similarly, assign the Toggle component to the socket_2_switch_lod_1 node of the right bedside switch and drag the LightOmni_1 node into the Control Node field.同样,将Toggle组件分配给右侧床头开关的socket_2_switch_lod_1节点,并将LightOmni_1节点拖到Control Node字段中。

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

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