In Nau Engine, users will be presented with two options for working with controllers at different levels of complexity. This article will cover one of them, which is more similar to classic models - requesting button states, offset and coordinate data from input devices within the update functions of game object system components.
Preparing
The approach we will be covering requires writing custom component code.
You will also need a development environment where you can open your project's code and the script you've created. We recommend that you read our article on creating game logic in more detail.
Game Object Component
The polling method of querying the input system is one of the basic techniques used in software development. To implement this approach, we need:
- The input API that returns values when queried.
- A function that will be called by the engine every frame.
Component Header File
It's also important to include necessary directives #include for engine systems.
#include "nau/scene/components/component.h"
#include "nau/scene/components/component_life_cycle.h"
#include "nau/scene/scene_object.h"
In the header file, you need to inherit the interface IComponentUpdate, along with the required base class Component.
You must also specify NAU_OBJECT (listing the component class and its parent classes) and NAU_DECLARE_DYNAMIC_OBJECT.
After that, you can proceed to declare necessary functions and variables.
Let's consider an example of the function void updateComponent(float dt) override;, which is required for our code implementation and several variables.
Here's a C++ code example:
playerController.h
#pragma once
#include "nau/scene/components/component.h"
#include "nau/scene/components/component_life_cycle.h"
#include "nau/scene/scene_object.h"
class PlayerController final : public nau::scene::Component,
public nau::scene::IComponentUpdate
{
NAU_OBJECT( PlayerController, nau::scene::Component, nau::scene::IComponentUpdate)
NAU_DECLARE_DYNAMIC_OBJECT
public:
void updateComponent(float dt) override;
private:
// Declare variables and functions for component work.
};
In private section, enumerations are declared to switch input states, as well as some floating-point variables used to adjust the object movement character.
Implementation of Component Class
After declaring the class, implement it. Here's an example code:
playerController.cpp
#include "playerController.h"
#include "nau/input.h"
NAU_IMPLEMENT_DYNAMIC_OBJECT(PlayerController)
void PlayerController::updateComponent(float dt)
{
// Update function called every frame..
}
In the example, necessary include directives are specified:
- The header file of the class (Component.h)
- #include "nau/input.h" for accessing Nau Engine input system.
All code will be written in the body of the updateComponent(float dt) function {}.
You can verify that your component is correctly configured by using logging messages through NAU_LOG_DEBUG("Debug message");. However, please avoid overloading the console with an excessive number of debug messages in each frame, as this can lead to performance issues and potentially lose other important logs."
Using Nau Input
Let's emphasize again: to access the input system functions, you need to include the directive #include "nau/input.h". This will allow you to use the API of the input system.
Now that we have set up the necessary includes, we can start writing code that responds to button presses.
The nau::input class provides basic functions for reading keyboard and mouse input. You can find a complete list of available functions and variables in the Nau Engine API documentation. For example, let's consider how to access keyboard and mouse input.
Keyboard Signals
To read keyboard button press events, you can use the nau::input::isKeyboardButtonPressed function. It takes two arguments: the keyboard index (usually 0) and the key to track as a member of the nau::input::Key enumeration.
The nau::input::Key enumeration includes all basic keyboard keys, regardless of the keyboard layout. Additional non-standard keys should be tested separately.
The nau::input::isKeyboardButtonHold function allows you to check if a specific key is held down in the current frame.
Here's an example:
bool isWalking = nau::input::isKeyboardButtonHold(0, nau::input::Key::W);
Both functions return a boolean value, so they can be used directly in conditional expressions.
Mouse Signals
To work with the mouse, you can use the nau::input::getMouseAxisValue function to read the cursor coordinates and nau::input::getMouseAxisDelta function to get the delta value of the mouse position relative to the previous frame.
Note that in the current implementation, the nau::input::MouseKey enumeration contains not only button numbers but also indices. The coordinate retrieval functions return a float type, so you need to specify the mouse index as the first argument and the axis from the MouseKey enumeration as the second argument.
Example:
float mouseDeltaX = nau::input::getMouseAxisDelta(0, nau::input::MouseKey::AxisX);
float mouseDeltaY = nau::input::getMouseAxisDelta(0, nau::input::MouseKey::AxisY);
To get the state of a mouse button in the current frame, use nau::input::isMouseButtonHold. If a mouse button was just pressed, nau::input::isMouseButtonPressed returns true. To determine if a mouse button has been released recently, use nau::input::isMouseButtonReleased.
The argument of type nau::input::MouseKey specifies which button is being referred to.
Using conditional operators allows you to execute code depending on the values returned by the system in the current frame.
For example:
if (nau::input::isMouseButtonPressed(0, nau::input::MouseKey::Button0)) {
NAU_LOG_DEBUG("Left mouse button was pressed");
}
Inside the condition, you can perform necessary actions, such as making a jump or moving the character in a certain direction.
Using this method, you can apply various control methods using both the keyboard and mouse.
Summary
With the basic functions described in this article, you can set up control that will be suitable for most common game mechanics. For further self-study and additional information on controlling, refer to the manual.