This page has been translated automatically.
Unigine Basics
1. Introduction
2. Managing Virtual Worlds
3. Preparing 3D Models
4. Materials
5. Cameras and Lighting
7. Making Cutscenes and Recording Videos
8. Preparing Your Project for Release
9. Physics
10. Optimization Basics
11. PROJECT2: First-Person Shooter
12. PROJECT3: Third-Person Cross-Country Arcade Racing Game
13. PROJECT4: VR Application With Simple Interaction

Solutions for Common Cases

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).

Open your project in an IDE - go to SDK Browser and choose Open Code IDE on your project's card.

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.

Copy the code below and paste it to the corresponding files in your project and save them in your IDE.

Notice
It is recommended to use Visual Studio as a default IDE.
Interactable.h (C++)
#include <UnigineComponentSystem.h>

class Interactable : public Unigine::ComponentBase
{
public:
	// declare constructor and destructor for our class and define the name of the property to be associated with the component.
	// The Interactable.prop file containing all parameters listed below will be generated in your project's data folder after running the app for the first time
	COMPONENT_DEFINE(Interactable, ComponentBase);

	// declare component parameters and setting defaults
	PROP_PARAM(String, tooltip, "Info about the object");		// information about the interactive object

	// virtual method implementing the action with the specified number
	virtual void action(int num = 0) {};
	// method that displays the tooltip using Visualizer
	void displayInfo();
};
Interactable.cpp (C++)
#include "Interactable.h"
#include <UnigineVisualizer.h>

// registering the Interactable component
REGISTER_COMPONENT(Interactable);
using namespace Unigine;
using namespace Math;

// method displaying a tooltip about the type of the interactive object and its functionality
void Interactable::displayInfo()
{
	// display a tooltip using the 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.

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.

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:
	// declare constructor and destructor for our class and define the name of the property to be associated with the component.
	// The Toggle.prop file containing all parameters listed below will be generated in your project's data folder after running the app for the first time
	COMPONENT_DEFINE(Toggle, Interactable);

	PROP_PARAM(Node, controlNode, nullptr);			// controlled node
	
	// registering a method to be called at the initialization stage of the world logic (the method is declared in the protected-section below)
	COMPONENT_INIT(init);

	// overloading of the Action method that implements the switching of the controlled node
	void action(int num = 0);

protected:
	// declaration of the component initialization method
	void init();
};
Toggle.cpp (C++)
#include "Toggle.h"
#include <UnigineLog.h>

// registration of the Toggle component
REGISTER_COMPONENT(Toggle);

using namespace Unigine;
using namespace Math;

// component initialization method
void Toggle::init()
{
	// if no controlled node is assigned, print the corresponding warning to the console
	if (!controlNode)
		Log::message("No control node is assigned for the %s node!\n", node->getName());
	else
		// set the tooltip text that will be displayed when the cursor hovers over the object
		tooltip = Unigine::String::format("Switches on and off the controlled node (%s) on RMB click.", controlNode->getName());
}

// overloading of the Action method that implements the switching of the controlled node
void Toggle::action(int num)
{
	// action indices other than zero are invalid for this component, therefore they are ignored
	if (num != 0)
		return;

	// check if the controlled node is assigned
	if (controlNode)
	{
		// switch the state of the controlled node
		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.

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.

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.

Last update: 2024-11-06
Build: ()