This page has been translated automatically.
Основы UNIGINE
1. Введение
2. Виртуальные миры и работа с ними
3. Подготовка 3D моделей
4. Материалы
5. Камеры и освещение
7. Создание кат-сцен и запись видео
8. Подготовка проекта к релизу
9. Физика
10. Основы оптимизации
11. ПРОЕКТ2: Шутер от первого лица
12. ПРОЕКТ3: Аркадная гонка по пересеченной местности от 3-го лица
13. ПРОЕКТ4: VR приложение с простым взаимодействием

Решение типовых задач

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.В данном разделе курса мы рассмотрим примеры решения типовых задач и используем полученный опыт для реализации того или иного функционала в нашем ArchViz-проекте.

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 (этот класс используется для отрисовки всевозможной дополнительной информации, которая может пригодиться как для отладки, так и для других целей).

Open your project in an IDE - go to SDK Browser and choose Open Code IDE on your project's card.Откроем проект в IDE - для этого перейдем в SDK Browser на вкладку Projects и выберем Open Code 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.Скопируйте приведенный ниже код, вставьте его в соответствующие файлы в вашем проекте и сохраните изменения.

Примечание
It is recommended to use Visual Studio as a default IDE.Рекомендуется в качестве IDE использовать Visual Studio.
Interactable.h (C++)
#include <UnigineComponentSystem.h>

class Interactable : public Unigine::ComponentBase
{
public:
	// Объявляем конструктор и деструктор для нашего класса, а также задаем имя связанного с компонентом свойства (property). 
	// Файл Interactable.prop со всеми описанными ниже параметрами будет сгенерирован Компонентной системой в папке 'data' вашего проекта при первом запуске приложения
	COMPONENT_DEFINE(Interactable, ComponentBase);

	// объявляем параметры компонента и задаем начальные значения
	PROP_PARAM(String, tooltip, "Info about the object");		// Информация об интерактивном объекте

	// виртуальный метод для реализации действий с интерактивным объектом (реализуется в классах-наследниках)
	virtual void action(int num = 0) {};
	// метод, отображающий подсказку с информацией о типе интерактивного объекта и его функционале
	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.Теперь, от предыдущего компонента унаследуем компоненту 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 и вместо стандартного базового класса ComponentBase укажите Interactable.

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). 
	// Файл Toggle.prop со всеми описанными ниже параметрами будет сгенерирован Компонентной системой в папке 'data' вашего проекта при первом запуске приложения
	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, чтобы Компонентная система сгенерировала property для связи компонента с нодой. После запуска приложения закроем его и вернемся в 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 левого прикроватного выключателя и перетащим в поле Control Node ноду LightOmni_0.

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 правого прикроватного выключателя и перетащим в поле Control Node ноду LightOmni_1.

Последнее обновление: 06.11.2024
Build: ()