Action set module
This module allows you to define and manage various input actions for your game, including keyboard, mouse and gamepad inputs. This system operates at higher-level concepts than simply pressing a certain key or taking the mouse position. The processing of all input data is combined into named structures called Actions, and includes all possible types of inputs.
The input action system is based on the concepts of Action and ActionSet. An Action represents a named input structure (such as a button press for jump or a joystick movement for player move), which can be defined for different input devices (keyboard, mouse, gamepad) at once. An ActionSet is a named collection of these structures, that allows you to group related actions together and activate or deactivate them as needed. It making it easier to handle player input regardless of specific input devices.
To add this module to your project, add the following line to your project file:
require engine.input_core // or require engine.core
Start using the input action system by defining actions and action sets in your game code. Let’s consider an action set that can be added as a description of the player’s behavior. It consists of the most common actions used in games:
var playerActionSet : ActionSet = {
"Move" => Action( // 2D vector-related action, describes joystick and keyboard continues inputs and can be used for character movement
joystickActions = JoystickAction(
sticks = [GamepadStickInput(xIdx=GamepadAxis.LThumbH, yIdx=GamepadAxis.LThumbV)],
keyboardDPads = [KeyboardDPadInput(leftIdx=KeyCode.A, rightIdx=KeyCode.D, upIdx=KeyCode.W, downIdx=KeyCode.S)]
)
),
"DPad" => Action( // 2D vector-related action, describes joystick and keyboard discrete inputs
joystickActions = JoystickAction(
keyboardDPads = [KeyboardDPadInput(leftIdx=KeyCode.Left, rightIdx=KeyCode.Right, upIdx=KeyCode.Up, downIdx=KeyCode.Down)],
gamepadDPads = [GamepadDPadInput(leftIdx=GamepadButton.Left, rightIdx=GamepadButton.Right, upIdx=GamepadButton.Up, downIdx=GamepadButton.Down)]
)
),
"Up" => Action( // button-related action, describes keyboard and gamepad discrete inputs, can be used for ui navigation or other purposes
buttonActions = ButtonAction(
keyboardButtons = [KeyboardButtonInput(idx=KeyCode.Up), KeyboardButtonInput(idx=KeyCode.Numpad8)],
gamepadButtons = [GamepadButtonInput(idx=GamepadButton.Up)]
)
),
"Down" => Action( // button-related action, describes keyboard and gamepad discrete inputs, can be used for ui navigation or other purposes
buttonActions = ButtonAction(
keyboardButtons = [KeyboardButtonInput(idx=KeyCode.Down), KeyboardButtonInput(idx=KeyCode.Numpad5)],
gamepadButtons = [GamepadButtonInput(idx=GamepadButton.Down)]
)
),
"Ok" => Action( // button-related action, describes keyboard and gamepad discrete inputs
buttonActions = ButtonAction(
keyboardButtons = [KeyboardButtonInput(idx=KeyCode.Return)],
gamepadButtons = [GamepadButtonInput(idx=GamepadButton.A)]
)
),
"Back" => Action( // button-related action, describes keyboard and gamepad discrete inputs
buttonActions = ButtonAction(
keyboardButtons = [KeyboardButtonInput(idx=KeyCode.Back)],
gamepadButtons = [GamepadButtonInput(idx=GamepadButton.B)]
)
),
}
The above code defines a action set called playerActionSet which includes various actions (such as Move, DPad, Up, Down, Ok, Back) for movement, d-pad input and common button actions.
You can add any other action sets besides that one to your game. For example, you may need a custom action set to control camera regardless of the player movement. It could look like this:
let cameraActionSet : ActionSet = {
"Rotate" => Action( // pointer related action, describes mouse and gamepad stick inputs with non accumulated returning values
pointerActions = PointerAction(
valueType = ValueType.Delta,
mouse = MouseInput(active=true),
gamepadPointers = [GamepadPointerInput(xIdx=GamepadAxis.LThumbH, yIdx=GamepadAxis.LThumbV)]
)
),
"Zoom" => Action( // trigger related action, describes mouse wheel and gamepad discrete accumulator inputs which not accumulated their values
triggerActions = TriggerAction(
valueType = ValueType.Delta,
mouseAccumulators = [MouseAccumulatorInput(incIdx=MouseButton.WheelUp, decIdx=MouseButton.WheelDown)],
gamepadAccumulators = [GamepadAccumulatorInput(sensitivity=50f, incIdx=GamepadButton.RightBumper, decIdx=GamepadButton.LeftBumper)]
)
)
}
After defining the action set, you need to add it to the game using the add_action_set function. This allows you to operate the actions in your game logic. For ability to direct return of the state of the actions, it needs to be activated with the activate_action_set function.
Type aliases
- ActionSet = table<string;variant<buttonActions:ButtonAction;axisActions:AxisAction;triggerActions:TriggerAction;joystickActions:JoystickAction;pointerActions:PointerAction>>
Action set definition - named table of actions, where keys are action names and values can be one of the action types
- variant Action
Action config for all actions, which can be used for getting there state values
- Variants:
buttonActions : ButtonAction - Digital buttons (can be pressed, justPressed or justReleased)
axisActions : AxisAction - Axis actions (axis with positive and negative directions from -1 to 1)
triggerActions : TriggerAction - Triggers (axis with positive direction from 0 to 1) and accumulators (clickable actions with discrete values)
joystickActions : JoystickAction - Joysticks (vector2 value with positive and negative directions from -1 to 1)
pointerActions : PointerAction - Cursor pointers
Enumerations
- GamepadAxis
Indices of gamepad axes, can be axis (-1, 1) or triggers (0, 1)
- Values:
LThumbH = 0 - Left stick horizontal (-1, 1)
LThumbV = 1 - Left stick vertical (-1, 1)
RThumbH = 2 - Right stick horizontal (-1, 1)
RThumbV = 3 - Right stick vertical (-1, 1)
LTrigger = 4 - Left trigger (0, 1)
RTrigger = 5 - Right trigger (0, 1)
LRTrigger = 6 - Left and right triggers combined (right trigger increases to 1, left trigger decreases to -1)
- ValueType
Types of state values returned by actions
- Values:
Delta = 0 - Delta value - change from last frame
Accumulate = 1 - Accumulated value - change over time
Structures
- KeyboardButtonInput
Keyboard button by index and keyboard modifiers
- Fields:
idx : KeyCode - Key index
modifier : KeyboardShifts - Keyboard modifiers bit flags
- MouseButtonInput
Mouse button by index and keyboard modifiers
- Fields:
idx : MouseButton - Mouse button index
modifier : KeyboardShifts - Keyboard modifiers bit flags
- GamepadButtonInput
Gamepad button by index
- Fields:
idx : GamepadButton - Gamepad button index
gamepadIdx : ControllerIndex - Index of gamepad controller
- ButtonAction
Action config for digital buttons (e.g. keyboard, mouse, gamepad buttons)
- Fields:
keyboardButtons : array< KeyboardButtonInput > - List of keyboard buttons
mouseButtons : array< MouseButtonInput > - List of mouse buttons
gamepadButtons : array< GamepadButtonInput > - List of gamepad buttons
- GamepadAxisInput
Continuous gamepad axis (sticks axis or combined triggers)
- Fields:
idx : GamepadAxis - Gamepad axis index GamepadAxis
isInverted : bool = false - Is axis inversed
gamepadIdx : ControllerIndex - Index of gamepad controller
- KeyboardBtnAxisInput
Discrete keyboard axis (negative and positive keys)
- GamepadBtnAxisInput
Discrete gamepad axis (negative and positive buttons)
- Fields:
negativeIdx : GamepadButton - Negative button index
positiveIdx : GamepadButton - Positive button index
gamepadIdx : ControllerIndex - Index of gamepad controller
- AxisAction
Action config for axis controls with bidirectional input ranging from -1 to 1 (e.g. steering wheels, analog sticks)
- Fields:
stickAxis : array< GamepadAxisInput > - List of gamepad axes with continuous values
keyboardAxis : array< KeyboardBtnAxisInput > - List of keyboard axis with discrete values (-1, 0, 1)
gamepadAxis : array< GamepadBtnAxisInput > - List of gamepad axis with discrete values (-1, 0, 1)
- KeyboardTriggerInput
Discrete keyboard trigger
- Fields:
maxIdx : KeyCode - Keyboard key index
- GamepadTriggerInput
Continuous or discrete gamepad trigger, set one of maxIdx or axisIdx (can be combined to simulate triggers on old gamepads)
- Fields:
axisIdx : GamepadAxis - Gamepad axis index GamepadAxis
maxIdx : GamepadButton - Gamepad button index
gamepadIdx : ControllerIndex - Index of gamepad controller
- KeyboardAccumulatorInput
Keyboard accumulator - clickable action which can be incremented and decremented
- Fields:
- GamepadAccumulatorInput
Gamepad accumulator - clickable action which can be incremented and decremented
- Fields:
sensitivity : float - Multiplier for state value
incIdx : GamepadButton - Increment gamepad button index
decIdx : GamepadButton - Decrement gamepad button index
gamepadIdx : ControllerIndex - Index of gamepad controller
- MouseAccumulatorInput
Mouse accumulator - clickable action which can be incremented and decremented, e.g. mouse wheel
- Fields:
sensitivity : float - Multiplier for state value
incIdx : MouseButton - Increment mouse button
decIdx : MouseButton - Decrement mouse button
- TriggerAction
Action config for triggers (axis with positive direction from 0 to 1) and accumulators (clickable actions with discrete values)
- Fields:
valueType : ValueType - Type of state value
keyboardTriggers : array< KeyboardTriggerInput > - List of keyboard triggers with discrete values (0 or 1)
gamepadTriggers : array< GamepadTriggerInput > - List of gamepad triggers with discrete or continuous values (0 or 1)
keyboardAccumulators : array< KeyboardAccumulatorInput > - List of keyboard accumulators (clickable actions which can be incremented and decremented)
gamepadAccumulators : array< GamepadAccumulatorInput > - List of gamepad accumulators (clickable actions which can be incremented and decremented)
mouseAccumulators : array< MouseAccumulatorInput > - List of mouse accumulators (clickable actions, e.g. mouse wheel)
- GamepadStickInput
Continuous gamepad stick
- Fields:
xIdx : GamepadAxis - Horizontal axis index GamepadAxis
yIdx : GamepadAxis - Vertical axis index GamepadAxis
isXInverted : bool = false - Is horizontal axis inversed
isYInverted : bool = false - Is vertical axis inversed
deadZone : float = 0f - Dead zone (value range 0 to 1)
gamepadIdx : ControllerIndex - Index of gamepad controller
- KeyboardDPadInput
Discrete keyboard DPads
- Fields:
- GamepadDPadInput
Discrete gamepad DPads
- Fields:
leftIdx : GamepadButton - Negative horizontal button index
rightIdx : GamepadButton - Positive horizontal button index
upIdx : GamepadButton - Positive vertical button index
downIdx : GamepadButton - Negative vertical button index
gamepadIdx : ControllerIndex - Index of gamepad controller
- JoystickAction
Action config for joysticks (vector2 value with positive and negative directions from -1 to 1)
- Fields:
sticks : array< GamepadStickInput > - List of gamepad sticks with continuous values
keyboardDPads : array< KeyboardDPadInput > - List of keyboard DPads
gamepadDPads : array< GamepadDPadInput > - List of gamepad DPads
- MouseInput
Mouse cursor
- Fields:
active : bool - Activeness of mouse, set to true to enable
sensitivity : float - Multiplier for state value
- GamepadPointerInput
Gamepad cursor, can be used ONLY with ValueType.Delta!
- Fields:
sensitivity : float - Multiplier for state value
xIdx : GamepadAxis - Horizontal axis index
yIdx : GamepadAxis - Vertical axis index
isXInverted : bool = false - Is horizontal axis inversed
isYInverted : bool = false - Is vertical axis inversed
gamepadIdx : ControllerIndex - Index of gamepad controller
- PointerAction
Action config for absolute mouse pointers
- Fields:
valueType : ValueType - Type of state value
mouse : MouseInput - State of mouse cursor (enabled or disabled)
gamepadPointers : array< GamepadPointerInput > - List of gamepad button delta pointers
Functions
- add_action_set(setName: string; actionSet: ActionSet)
Adds an action set to the game. Action sets are used to define a group of actions that can be enabled or disabled together. After adding an action set, it can be activated or deactivated using activate_action_set and deactivate_action_set functions.
If an action with the same name already exists, an error is thrown and the function continues to the next action.
- Arguments:
setName : string - The name of the action set to add
actionSet : ActionSet - The ActionSet (a table of action names to actions) to add
Usage example:
add_action_set("player", {
"jump" => Action(
buttonActions = ButtonAction(
keyboardButtons = [KeyboardButtonInput(idx=KeyCode.Space)],
gamepadButtons = [GamepadButtonInput(idx=GamepadButton.A)]
)
),
"speed" => Action(
axisActions = AxisAction(
keyboardAxis = [KeyboardBtnAxisInput(negativeIdx=KeyCode.Left, positiveIdx=KeyCode.Right)],
stickAxis = [GamepadAxisInput(idx=GamepadAxis.LRTrigger)]
)
),
"move" => Action(
joystickActions = JoystickAction(
keyboardDPads = [KeyboardDPadInput(leftIdx=KeyCode.A, rightIdx=KeyCode.D, upIdx=KeyCode.W, downIdx=KeyCode.S)],
sticks = [GamepadStickInput(xIdx=GamepadAxis.LThumbH, yIdx=GamepadAxis.LThumbV)]
)
),
})
- remove_action_set(setName: string)
Removes an action set from the game. If the action set is active, it is deactivated automatically.
- Arguments:
setName : string - The name of the action set to remove
Usage example:
remove_action_set("player")
- has_action_set(setName: string): bool
Checks if an action set was added to the game.
- Arguments:
setName : string - The name of the action set to check
- Returns:
bool - true if the action set was added previously, false otherwise
Usage example:
if (has_action_set("player")) {
print("player action set exists, can be activated or deactivated")
}
- activate_action_set(setName: string; activate: bool = true)
Activates or deactivates an existing action set. After activating an action set, all actions in it will be enable and can be used for getting there state values.
- Arguments:
setName : string - The name of the action set to activate or deactivate
activate : bool - True to activate the action set (default), false to deactivate it
Usage example:
activate_action_set("player")
- add_and_activate_action_set(setName: string; actionSet: ActionSet)
Adds an action set to the game and activates it. Same as add_action_set and activate_action_set combined.
Usage example:
add_and_activate_action_set("player", {
"fly" => Action(
buttonActions = ButtonAction(
keyboardButtons = [KeyboardButtonInput(idx=KeyCode.Space)],
gamepadButtons = [GamepadButtonInput(idx=GamepadButton.A)]
)
),
"speed" => Action(
axisActions = AxisAction(
keyboardAxis = [KeyboardBtnAxisInput(negativeIdx=KeyCode.Left, positiveIdx=KeyCode.Right)],
stickAxis = [GamepadAxisInput(idx=GamepadAxis.LRTrigger)]
)
),
"move" => Action(
joystickActions = JoystickAction(
keyboardDPads = [KeyboardDPadInput(leftIdx=KeyCode.A, rightIdx=KeyCode.D, upIdx=KeyCode.W, downIdx=KeyCode.S)],
sticks = [GamepadStickInput(xIdx=GamepadAxis.LThumbH, yIdx=GamepadAxis.LThumbV)]
)
),
})
- Arguments:
setName : string
actionSet : ActionSet
- deactivate_action_set(setName: string)
Deactivates an existing action set. After deactivating an action set, all actions in it will be disabled and cannot be used for getting there state values.
- Arguments:
setName : string - The name of the action set to deactivate
Usage example:
deactivate_action_set("player")
// let currentDirection = get_action_vector2("move") - will return nothing
- is_action_set_active(setName: string): bool
Checks if an action set is active.
- Arguments:
setName : string - The name of the action set to check
- Returns:
bool - true if the action set is active, false otherwise
Usage example:
if (is_action_set_active("player")) {
print("player action set is active, actions can return state values")
}
- enable_action_at_set(setName: string; actionName: string; enable: bool = true)
Activates or deactivates an action in an existing action set. By default, all actions of an action set are enabled after activating the action set.
- Arguments:
setName : string - The name of action set which contains the action
actionName : string - The name of the action to activate or deactivate
enable : bool - True to activate the action (default), false to deactivate it
Usage example:
enable_action_at_set("player", "move")
let currentDirection = get_action_vector2("move")
- disable_action_at_set(setName: string; actionName: string)
Deactivates an action in an existing action set
- Arguments:
setName : string - The name of action set which contains the action
actionName : string - The name of the action to deactivate
Usage example:
disable_action_at_set("player", "move")
// let currentDirection = get_action_vector2("move") - wouldn't return anything
- is_action_state_active(actionName: string): bool
Checks if an action is active. An action is active if it is enabled and returns some non-default value.
- Arguments:
actionName : string - The name of the action to check
- Returns:
bool - true if the action is active, false otherwise
Usage example:
if (is_action_state_active("move")) {
print("player is moving in some direction")
} else {
print("player is not moving, joystick action returns default zero value")
}
if (is_action_state_active("fly")) {
print("player is flying")
} else {
print("player is not flying, button action was not pressed or released")
}
- is_action_pressed(actionName: string): bool
Checks if a button action is pressed (ongoing action, it’s true as long as the button is held down).
- Arguments:
actionName : string - The name of the button action to check
- Returns:
bool - true if the button action is pressed, false otherwise
Usage example:
if (is_action_pressed("fly")) {
print("player is flying (KeyCode.Space or GamepadButton.A btn is pressed)")
player.start_flying()
}
- is_action_just_pressed(actionName: string): bool
Checks if a button action was just pressed, during the current frame.
- Arguments:
actionName : string - The name of the button action to check
- Returns:
bool - true if the button action was just pressed, false otherwise
Usage example:
if (is_action_just_pressed("fly")) {
print("player just started flying (KeyCode.Space or GamepadButton.A btn was just pressed)")
player.fly()
}
- is_action_just_released(actionName: string): bool
Checks if a button action was just released, during the current frame.
- Arguments:
actionName : string - The name of the button action to check
- Returns:
bool - true if the button action was just released, false otherwise
Usage example:
if (is_action_just_released("fly")) {
print("player just stopped flying (KeyCode.Space or GamepadButton.A btn was just released)")
player.stop_flying()
}
- get_action_axis(actionName: string): float
Returns the current value of an enabled axis action.
- Arguments:
actionName : string - The name of the axis action to check
- Returns:
float - The current value of the axis action (1D value), or 0 if the action 1. is not an axis action (trigger or axis action) 2. the action is disabled 3. action set is inactive
Usage example:
let currentSpeed = get_action_axis("speed") * characterSpeed
- get_action_vector2(actionName: string): float2
Returns the current value of an enabled vector2 action.
- Arguments:
actionName : string - The name of the vector2 action to check
- Returns:
float2 - The current value of the vector2 action (2D vector), or (0, 0) if the action 1. is not a vector2 action (joystick or pointer action) 2. the action is disabled 3. action set is inactive
Usage example:
let currentDirection = get_action_vector2("move")
- has_gamepad_with_action_set(gamepad_idx: ControllerIndex = input_consts::ControllerIndex.Device0): bool
Raw input function. Returns true if the gamepad with the given index was connected
- Arguments:
gamepad_idx : ControllerIndex
- is_any_keyboard_button_pressed(): bool
Raw input function. Returns true if any keyboard button is pressed
- is_any_mouse_button_pressed(): bool
Raw input function. Returns true if any mouse button is pressed
- is_any_gamepad_button_pressed(): bool
Raw input function. Returns true if any gamepad button is pressed
- is_any_button_pressed(): bool
Raw input function. Returns true if any button of any input device is pressed
- is_any_gamepad_stick_touched(): bool
Raw input function. Returns true if any gamepad stick is touched (has non-zero value)
- is_any_gamepad_slider_touched(): bool
Raw input function. Returns true if any gamepad slider is touched (has non-zero value)
- is_any_gamepad_touched(): bool
Raw input function. Returns true if any gamepad button, stick or slider is touched
- is_mouse_moved(): bool
Raw input function. Returns true if the mouse has moved since the last frame
- is_any_mouse_touched(): bool
Raw input function. Returns true if the mouse has moved or any mouse button is pressed