Jump to content

Some questions about workflow on Unigine(Editor and C++)


photo

Recommended Posts

Posted

Probably a very basic question, please forgive me. How do you use Unigine's C++ workflow to create a menu page (the kind of game start page that fills the screen in 2D)? I created two files, MainMenu.h and MainMenu.cpp, but I don't know how to get the UNIGINE-built game runtime to load this page first and show two buttons with click-to-interact logic. Also, I have doubts about parameters; a YouTube tutorial shows that the parameters under Dummynode in his editor have some of his properties, but I can't do that.

Can anyone help me? Thank you.

Posted

Hi, @Capixo!

Here is a simple example of the start menu implemented in a C++ component. With a complete step-by-step instruction on how to use it.

 

1. Open Project in 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.

edit_code.png

2. Add New C++ Component Class

In an IDE create a new C++ class (Project → Add Class) and call it StartMenu.

add_class_menu.png

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

image.png

Two files StartMenu.h and StartMenu.cpp will be added to your C++ project.

3. Write Component Code

Copy and paste the following code to the  StartMenu.h and StartMenu.cpp  files.

StartMenu.h

#pragma once
#include <UnigineComponentSystem.h>
#include <UnigineGui.h>
class StartMenu :
    public Unigine::ComponentBase
{
public:
	// component constructor and the list of methods
	COMPONENT_DEFINE(StartMenu, ComponentBase);
	// -------------------------------
	COMPONENT_INIT(init);
	COMPONENT_SHUTDOWN(shutdown);

	Unigine::WidgetSpritePtr bgimage = nullptr;
	Unigine::WidgetVBoxPtr vbox = nullptr;
	PROP_PARAM(String, menuTitle, "Start Menu", "Menu Title");
	PROP_PARAM(Int, menuFontSize, 30, "Font size");
	PROP_PARAM(File, bgImage, "Background Image");
	PROP_PARAM(Color, bgColor, Unigine::Math::vec4(0.1f, 0.8f, 0.1f, 0.7f), "Background Color");

private:
	// auxiliary variable used to manage event subscriptions
	Unigine::EventConnections econn;

	// proxy-handlers calling handlers according to subscriptions
	void onStartClicked();
	void onQuitClicked();

protected:
	// main loop overrides
	void init();
	void shutdown();
};

StartMenu.cpp

#include "StartMenu.h"
REGISTER_COMPONENT(StartMenu);

using namespace Unigine;
using namespace Math;

// component initialization method
void StartMenu::init()
{
	GuiPtr screenGui = Gui::getCurrent();

	// creating a background image and a vbox-container for the menu
	bgimage = WidgetSprite::create(screenGui, Unigine::FileSystem::guidToPath(FileSystem::getGUID(bgImage.getRaw())));
	bgimage->setLifetime(Widget::LIFETIME_WORLD);
	vbox = WidgetVBox::create(screenGui);
	vbox->setPermanentFocus();
	vbox->setLifetime(Widget::LIFETIME_WORLD);
	vbox->setWidth(200);

	// configuring the background for the menu
	vbox->setBackground(1);
	vbox->setBackgroundColor(bgColor);

	// Creating a menu title and two buttons
	WidgetLabelPtr title_label = WidgetLabel::create(screenGui, menuTitle);
	title_label->setFontSize(menuFontSize);
	title_label->setTextAlign(Gui::ALIGN_CENTER);
	WidgetButtonPtr button_start = WidgetButton::create(screenGui, "Start the Game");
	WidgetButtonPtr button_exit = WidgetButton::create(screenGui, "Quit");
	
	// subscribing to click events for both buttons
	button_start->getEventClicked().connect(econn, this, &StartMenu::onStartClicked);
	button_exit->getEventClicked().connect(econn, this, &StartMenu::onQuitClicked);
	
	// adding a title and buttons to the menu
	vbox->addChild(title_label);
	vbox->addChild(WidgetSpacer::create(screenGui));
	vbox->addChild(button_start);
	vbox->addChild(button_exit);
	vbox->addChild(WidgetSpacer::create(screenGui));

	// adding a background sprite and the menu to the Engine GUI
	screenGui->addChild(bgimage, Gui::ALIGN_BACKGROUND | Gui::ALIGN_EXPAND);
	screenGui->addChild(vbox, Gui::ALIGN_OVERLAP | Gui::ALIGN_CENTER);
}


void StartMenu::shutdown()
{
	// removing all event subscriptions
	econn.disconnectAll();
}

// handler to be executed on clicking the Start button
void StartMenu::onStartClicked()
{
	vbox->removeFocus();
	vbox->setHidden(true);
	bgimage->setHidden(true);
	Input::setMouseGrab(true);
	ControlsApp::setMouseEnabled(true);

	// start the game
}

// handler to be executed on clicking the Quit button
void StartMenu::onQuitClicked()
{
	// quit the application
	Engine::get()->quit();
}

4. Compile And Run To Generate Property

Don't forget to set the appropriate platform and configuration settings for your project before compiling your code in Visual Studio.

ide_project_settings.png

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.

5. Assign Component To Nodes In Editor

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.

image.png

The component is ready, but now it must be assigned to some node, otherwise its code won't be executed. Create a new NodeDummy, select it, then add the StartMenu property to it via the Parameters window (Add New Property button). In the Parameters window set the desired background image, title text and font size, and save the world by hitting Ctrl + S.

image.gif

Now, you can launch your application via the SDK Browser by selecting the project on the Projects tab and clicking Run. But first, 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).

customize_run_debug.png

Check if the menu works as intended! Should look somewhat like this:

image.png

Hope this helps!

 

 

  • Like 1
Posted

Hello, @fox

7 hours ago, fox said:

Hi, @Capixo!

Here is a simple example of the start menu implemented in a C++ component. With a complete step-by-step instruction on how to use it.

 

1. Open Project in 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.

edit_code.png

2. Add New C++ Component Class

In an IDE create a new C++ class (Project → Add Class) and call it StartMenu.

add_class_menu.png

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

image.png

Two files StartMenu.h and StartMenu.cpp will be added to your C++ project.

3. Write Component Code

Copy and paste the following code to the  StartMenu.h and StartMenu.cpp  files.

StartMenu.h

#pragma once
#include <UnigineComponentSystem.h>
#include <UnigineGui.h>
class StartMenu :
    public Unigine::ComponentBase
{
public:
	// component constructor and the list of methods
	COMPONENT_DEFINE(StartMenu, ComponentBase);
	// -------------------------------
	COMPONENT_INIT(init);
	COMPONENT_SHUTDOWN(shutdown);

	Unigine::WidgetSpritePtr bgimage = nullptr;
	Unigine::WidgetVBoxPtr vbox = nullptr;
	PROP_PARAM(String, menuTitle, "Start Menu", "Menu Title");
	PROP_PARAM(Int, menuFontSize, 30, "Font size");
	PROP_PARAM(File, bgImage, "Background Image");
	PROP_PARAM(Color, bgColor, Unigine::Math::vec4(0.1f, 0.8f, 0.1f, 0.7f), "Background Color");

private:
	// auxiliary variable used to manage event subscriptions
	Unigine::EventConnections econn;

	// proxy-handlers calling handlers according to subscriptions
	void onStartClicked();
	void onQuitClicked();

protected:
	// main loop overrides
	void init();
	void shutdown();
};

StartMenu.cpp

#include "StartMenu.h"
REGISTER_COMPONENT(StartMenu);

using namespace Unigine;
using namespace Math;

// component initialization method
void StartMenu::init()
{
	GuiPtr screenGui = Gui::getCurrent();

	// creating a background image and a vbox-container for the menu
	bgimage = WidgetSprite::create(screenGui, Unigine::FileSystem::guidToPath(FileSystem::getGUID(bgImage.getRaw())));
	bgimage->setLifetime(Widget::LIFETIME_WORLD);
	vbox = WidgetVBox::create(screenGui);
	vbox->setPermanentFocus();
	vbox->setLifetime(Widget::LIFETIME_WORLD);
	vbox->setWidth(200);

	// configuring the background for the menu
	vbox->setBackground(1);
	vbox->setBackgroundColor(bgColor);

	// Creating a menu title and two buttons
	WidgetLabelPtr title_label = WidgetLabel::create(screenGui, menuTitle);
	title_label->setFontSize(menuFontSize);
	title_label->setTextAlign(Gui::ALIGN_CENTER);
	WidgetButtonPtr button_start = WidgetButton::create(screenGui, "Start the Game");
	WidgetButtonPtr button_exit = WidgetButton::create(screenGui, "Quit");
	
	// subscribing to click events for both buttons
	button_start->getEventClicked().connect(econn, this, &StartMenu::onStartClicked);
	button_exit->getEventClicked().connect(econn, this, &StartMenu::onQuitClicked);
	
	// adding a title and buttons to the menu
	vbox->addChild(title_label);
	vbox->addChild(WidgetSpacer::create(screenGui));
	vbox->addChild(button_start);
	vbox->addChild(button_exit);
	vbox->addChild(WidgetSpacer::create(screenGui));

	// adding a background sprite and the menu to the Engine GUI
	screenGui->addChild(bgimage, Gui::ALIGN_BACKGROUND | Gui::ALIGN_EXPAND);
	screenGui->addChild(vbox, Gui::ALIGN_OVERLAP | Gui::ALIGN_CENTER);
}


void StartMenu::shutdown()
{
	// removing all event subscriptions
	econn.disconnectAll();
}

// handler to be executed on clicking the Start button
void StartMenu::onStartClicked()
{
	vbox->removeFocus();
	vbox->setHidden(true);
	bgimage->setHidden(true);
	Input::setMouseGrab(true);
	ControlsApp::setMouseEnabled(true);

	// start the game
}

// handler to be executed on clicking the Quit button
void StartMenu::onQuitClicked()
{
	// quit the application
	Engine::get()->quit();
}

4. Compile And Run To Generate Property

Don't forget to set the appropriate platform and configuration settings for your project before compiling your code in Visual Studio.

ide_project_settings.png

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.

5. Assign Component To Nodes In Editor

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.

image.png

The component is ready, but now it must be assigned to some node, otherwise its code won't be executed. Create a new NodeDummy, select it, then add the StartMenu property to it via the Parameters window (Add New Property button). In the Parameters window set the desired background image, title text and font size, and save the world by hitting Ctrl + S.

image.gif

Now, you can launch your application via the SDK Browser by selecting the project on the Projects tab and clicking Run. But first, 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).

customize_run_debug.png

Check if the menu works as intended! Should look somewhat like this:

image.png

Hope this helps!

 

 

Hello, @fox. Thank you for so much detailed step-by-step tutorial explaining. You are really so kind man. I find that in your in tutorial, you create a custom class(StartMenu class) by click 'Project-> Add Class', while I was just create cpp and head files in a new folder, MyGame/data/Scripts/StartMenu.cpp, which makes VS IDE doesn't consider it as belongs to project. However, if I put StartMenu.cpp under the folder, MyGame/source, which is folder with main.cpp together, this will lead the problem I can not find this cpp in Editor, when I want to add it to node as Script Setting. Do you know how to fix this issue?

I will add some screenshots to help you understand later, due to I am not with my workstation together for now. 

Still thank you for your detailed explaining above.

Posted

Hi, @Capixo!

Oh, now I see. Simply putting source files (*.cpp and *.h) to the project's folder does not automatically add it to the C++ project. To add existing files describing your component (or other sources you might need) to the project in Visual Studio you can simply right-click on your project's name in the Solution Explorer and choose Add-> Existing Item (or press Shift+Alt+A) and select your component's *.cpp and *.h files in the dialog that opens. After clicking Add both will be added to your project, so you can compile and run it to generate a property proceeding to Step 4 of the instruction given above.

image.png

Hope this helps!

Posted
19 hours ago, fox said:

Hi, @Capixo!

Oh, now I see. Simply putting source files (*.cpp and *.h) to the project's folder does not automatically add it to the C++ project. To add existing files describing your component (or other sources you might need) to the project in Visual Studio you can simply right-click on your project's name in the Solution Explorer and choose Add-> Existing Item (or press Shift+Alt+A) and select your component's *.cpp and *.h files in the dialog that opens. After clicking Add both will be added to your project, so you can compile and run it to generate a property proceeding to Step 4 of the instruction given above.

image.png

Hope this helps!

Thank you, it really helps a lot.

  • Like 1
×
×
  • Create New...