Input System
Introduction
One of the features the Unigine engine provides is a High-Level Input API. It allows to work with the variety of input devices (such as keyboard, mouse, joystick, gamepad etc.) in the same way, utilizing their capabilities simultaneously. For the sake of usability all input devices recognized by the engine have a common interface. The controls of the input devices can be assigned to definite user's actions in the virtual world. According to the application needs the editing of the controls using GUI can be enabled.
The Input scripts are located in data/scripts/input directory of the Unigine SDK.
Entities
Input device
Input device is a peripheral hardware equipment providing data and control signals to the processing unit. It is one of the key resources for the interactive virtual reality systems. Each input device regardless of its type has an ID and is characterized by the number and states of its axes and buttons.
Input
Input represents the input data provided to the engine.
Button
Button of the input device gives only off/on digital signal, indicating two discrete values: “0” and “1”. The user's application reacts accordingly.
Axis
Axis of the input device is an analogue signal data corresponding to the angle of displacement. It has three basic positions: minimum, neutral, and maximum. For Unigine engine it is recommended that they belong to the interval between -1.0 and 1.0, with 0 as a neutral value.
According to the characteristics of the axes they can be divided into 4 calibration types:
- Increasing axis - with the range from 0.0 to 1.0;
- Decreasing axis - with the range from 0.0 to -1.0;
- Positive axis with the range from -1.0 to 1.0;
- Negative axis with the range from 1.0 to -1.0.
Virtual axis
Virtual axis allows to emulate analogue signal using digital input device. It is used to implement smooth value changing, similar to a steering wheel rotation, for example. If a button with the virtual axis assigned is pressed continuously or repeatedly, virtual axis value will be incremented to 1.0 with the specified changing speed. When the button is no longer pressed, the axis value will be decremented to 0 with the returning speed.
Action
The user can perform a number of actions in the virtual world, such as moving in different directions, jumping, or shooting. The actions can be activated in many ways: by pressing a button or rotating an analogue stick of the gamepad. The Unigine engine makes it possible to assign multiple Inputs for each of the action. The names of the actions and input axes assigned to them can be saved in the configuration file.
Configuration file syntax
The syntax of the configuration stored in the XML file is the following:
<controls>
<action name="accelerate">
<input device="Logitec Racing Wheel" state="3" min="1" max="-1"/>
<input device="Keyboard" state="119"/>
</action>
<action name="brake">
<input device="Logitec Racing Wheel" state="2" min="1" max="-1"/>
<input device="Keyboard" state="115"/>
</action>
</controls>
Сontrols tag is used to describe control action map. Action tags are included into this tag.
Action tag describes action configuration, identified by its name (name attribute required). Action tag can contain Input tags.
Input tag contains input configuration. It has the following attributes:
- Device is a required attribute. It specifies input device name and is used to identify input device. Specifying keyboard and mouse as input devices is sufficient for all types of keyboards and mice.
- State is a required attribute. It specifies input device state number and is used to map input to a particular input device axis or button.
Direct names of the buttons can't be used, as each input device has its own states and state names. They also depend on the installed driver. Taking these facts into consideration, the names are not universal.
However, controls can be edited using GUI interface. In this case, there is no need to specify the exact state number and it is possible to see input state names. - Min is an optional attribute. It specifies the minimum input device axis value.
- Max is an optional attribute. It specifies the maximum input device axis value.
- Neutral specifies the neutral value, when input is inactive. The default is 0.
- Threshold specifies the threshold for input device response in decimal units. The default value is 0.2.
- Change_speed is an optional attribute. It specifies the axis changing speed.
- Return_speed is an optional attribute. It specifies the axis returning speed.
How to Use
Step 1. Include the required input devices headers:
#include <scripts/input/input_device.h>
#include <scripts/input/control.h>
Step 2. Add initialization, update and shutdown handlers to the initialization code:
Unigine::Input::init();
Unigine::Input::update();
Unigine::Input::shutdown();
Step 3. Create controls configuration files:
Create 2 configuration files: controls_def and controls.
Controls_def file defines the action attributes:
<?xml version="1.0" encoding="utf-8"?>
<controls_def>
<action_def name="accelerating" min="0" max="1" neutral="0" type="state"/>
</controls_def>
Action tag has the following attributes:
- Name — action name.
- Min — minimum axis value for application accepted input.
- Max — maximum axis value for application accepted input.
- Neutral — neutral axis value for application accepted input.
- Type — action type:
- State specifies the action having effect until the corresponding input is pressed. In other words, state action is used when it is necessary to change something continuously according to key / axis state. An example is car steering.
In the case of a state action, getState() returns the current input state (corrected according to the input range and action range).
- Switch is used when it is necessary to toggle something on and off. It allows to handle key up and key down events (just one at a time). An example is turning car head lights on and off.
In the case of a switch action, the current state is irrelevant, but rather the difference between the current and the previous state matters.
- When the key is pressed down, getState() returns the maximum value.
- When the key is up, getState() returns -1 * maximum value.
- If the key did not change its state since the previous update, the function will return the minimum value.
- State specifies the action having effect until the corresponding input is pressed. In other words, state action is used when it is necessary to change something continuously according to key / axis state. An example is car steering.
Controls file binds input with actions:
<?xml version="1.0" encoding="utf-8"?>
<controls definition="/config/controls/controls_def">
<controls>
<action name="accelerate"/>
<action name="brake"/>
<!-- etc. -->
</controls>
Step 4.
To load control configuration use:
// somewhere in initialization code
Control control = new Control();
control.loadFromFile("you_config_file.xml");
// somewhere in update code
control.update(engine.game.getIFps())
Action action = control.getAction("accelerate");
current_car.setAccelerator(action.getState());
action = control.getActionByName("brake");
current_car.setBrake(action.getState());
// etc.
Editing the controls using GUI interface
To enable this function do the following:
Step 1. Include headers:
#include <scripts/input/control_setup_window.h>
Step 2. Add initialization, update and shutdown handlers for ControlSetupWindow into corresponding code sections:
Unigine::Input::ControlSetupWindow::init(engine.getGui());
Unigine::Input::ControlSetupWindow::update();
Unigine::Input::ControlSetupWindow::shutdown();
Step 3. Example of the code used to show configuration window:
void cotroller_setup_button_clicked() {
if(controller_setup_button.isToggled()) {
// show window
Unigine::Input::ControlSetupWindow::addOnHideCallback("TestCarGui::on_save_car_controls",NULL);
Unigine::Input::ControlSetupWindow::show(control); // see control definition above
} else {
// hide window
Unigine::Input::ControlSetupWindow::hide();
}
}