This page has been translated automatically.
Unigine Basics
1. Introduction
2. Managing Virtual Worlds
3. Preparing 3D Models
4. Materials
5. Cameras and Lighting
6. Implementing Application Logic
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

Customizing Menu

The VR template has two menu types: the main one is attached to the HMD position, and the second — to the hand. In the VR sample, the head_menu node (ObjectGui) is used for the main menu, and the hand_menu node (ObjectGui) is used for the additional menu.

Attached Menus

Hand- and head-mounted menu nodes have the MixedRealityMenuGui and HandMenuSampleGui components assigned respectively. Both these components are inherited from the base MenuBaseUI component that implements a user interface. In general, the user interface is implemented as follows:

  1. Inherit a new component from the base MenuBaseUI.
  2. Implement the user interface with the required widgets in the overridden init_gui() method.
  3. Implement handlers for processing widgets events (pressing a button, selecting elements in the drop-down menu, etc.).
  4. Subscribe the corresponding widgets for the events in the init_gui() method.
  5. Assign the component to the ObjectGui node that will display the user interface.

Let's create a new menu for the left controller and add the quit button:

  1. Inherit a new component from the base MenuBaseUI, call it VRHandMenu and copy the following code to it:

    Source code (C++)
    #pragma once
    #include <UnigineComponentSystem.h>
    #include <UnigineGui.h>
    #include "../Demo/GUI/MenuBaseUI.h"
    class VRHandMenu :
        public MenuBaseUI
    {
    public:
    	COMPONENT_DEFINE(VRHandMenu, MenuBaseUI);
    	// инициализация UI (создание виджетов и т.д.)
    	virtual void init_gui() override;
    
    private:
    	// объявляем обработчики событий
    	void button_quit_clicked();
    	void ok_clicked();
    	void cancel_clicked();
    	void window_changed();
    
    	// ObjectGui background
    	Unigine::WidgetSpritePtr background;
    
    	// объявляем нужные виджеты
    	Unigine::WidgetVBoxPtr VBox;
    	Unigine::WidgetButtonPtr quitButton;
    	Unigine::WidgetWindowPtr window;
    	Unigine::WidgetButtonPtr okButton;
    	Unigine::WidgetButtonPtr cancelButton;
    	Unigine::WidgetHBoxPtr HBox;
    };
    Source code (C++)
    #include "VRHandMenu.h"
    REGISTER_COMPONENT(VRHandMenu);
    
    using namespace Unigine;
    using namespace Math;
    
    const int font_size = 25;
    
    void VRHandMenu::init_gui()
    {
    	if (!gui)
    		return;
    
    	// backgound
    	background = WidgetSprite::create(gui, "core/textures/common/black.texture");
    	background->setColor(Math::vec4(1.0f, 1.0f, 1.0f, 0.5f));
    	gui->addChild(background, Gui::ALIGN_BACKGROUND | Gui::ALIGN_EXPAND);
    
    	// добавляем в GUI контейнер WidgetVBox с вертикальным расположением виджетов
    	VBox = WidgetVBox::create();
    	VBox->setWidth(gui->getWidth());
    	VBox->setHeight(100);
    	gui->addChild(VBox, Gui::ALIGN_OVERLAP | Gui::ALIGN_CENTER);
    
    	// добавляем в контейнер кнопку, отображающую окно подтверждения выхода из приложения
    	quitButton = WidgetButton::create(gui, "QUIT APPLICATION");
    	quitButton->setFontSize(20);
    	VBox->addChild(quitButton);
    	quitButton->getEventClicked().connect(this, &VRHandMenu::button_quit_clicked);
    	VBox->arrange();
    
    	// создаем окно подтверждения выхода из приложения
    	window = WidgetWindow::create(gui, "Quit Application");
    	window->setFontSize(20);
    
    	// добавляем в окно контейнер WidgetHBox с горизонтальным расположением виджетов
    	HBox = WidgetHBox::create();
    	HBox->setWidth(window->getWidth());
    	HBox->setHeight(100);
    	window->addChild(HBox);
    
    	// добавляем в контейнер кнопку 'OK' c обработчиком 'OkClicked', закрывающим приложение
    	okButton = WidgetButton::create(gui, "OK");
    	okButton->setFontSize(20);
    	HBox->addChild(okButton);
    	okButton->getEventClicked().connect(this, &VRHandMenu::ok_clicked);
    
    	// добавляем в контейнер кнопку 'Cancel' c обработчиком 'CancelClicked', закрывающим окно подтверждения
    	cancelButton = WidgetButton::create(gui, "Cancel");
    	cancelButton->setFontSize(20);
    	HBox->addChild(cancelButton);
    	cancelButton->getEventClicked().connect(this, &VRHandMenu::cancel_clicked);
    }
    
    void VRHandMenu::button_quit_clicked()
    {
    	gui->addChild(window, Gui::ALIGN_OVERLAP | Gui::ALIGN_CENTER);
    }
    
    void VRHandMenu::ok_clicked()
    {
    	Engine::get()->quit();
    }
    
    void VRHandMenu::cancel_clicked()
    {
    	gui->removeChild(window);
    }
    
    void VRHandMenu::window_changed()
    {
    	// do not let the window go beyond the gui plane
    	int x = Math::clamp(window->getPositionX(), 0, window->getGui()->getWidth() - window->getWidth());
    	int y = Math::clamp(window->getPositionY(), 0, window->getGui()->getHeight() - window->getHeight());
    	window->setPosition(x, y);
    }
  2. Save these files and then build and run the application by hitting Ctrl + F5 to make the Component System generate a property to be used to assign the component to nodes. Close the application after running it and switch to UnigineEditor.

    Then assign the VRHandMenu property to the hand_menu node. And disable the HandMenuSampleGui property which is assigned to this node by default.

    Hand Menu

  3. Save changes (Ctrl+S) and run your application via SDK Browser.

After launching the application, press the Menu button on the left controller — the result will look similar to this:

Hand Menu Activated

Last update: 2024-12-13
Build: ()