Skip to content

Instantly share code, notes, and snippets.

@adriano-t
Last active June 2, 2026 06:03
Show Gist options
  • Select an option

  • Save adriano-t/bd8785dd8a46b641a98634e254f9c241 to your computer and use it in GitHub Desktop.

Select an option

Save adriano-t/bd8785dd8a46b641a98634e254f9c241 to your computer and use it in GitHub Desktop.
Input Manager for GameMaker Studio 2
enum InputSource {
KEYBOARD,
MOUSE,
GAMEPAD
}
enum GamepadType {
Xinput,
DirectInput,
}
global.input_manager_bindings = {};
global.input_manager_axes = {};
global.input_manager_current_type = InputSource.KEYBOARD;
global.input_manager_gamepad_type = GamepadType.Xinput;
global.input_manager_max_gamepads = 8;
global.input_manager_deadzone = 0.2;
global.input_manager_presszone = 0.8;
/**
* @function input_setup
* @description Setup the input manager.
* @param {array} _bindings The bindings for the input manager.
* @param {array} _axes The axes for the input manager.
*/
function input_setup(_bindings, _axes) {
global.input_manager_bindings = {};
global.input_manager_axes = {};
global.input_manager_current_type = InputSource.KEYBOARD;
for (var _i = 0; _i < array_length(_bindings); _i++) {
var _binding = variable_clone(_bindings[_i])
global.input_manager_bindings[$ _binding.id] = _binding;
}
for (var _i = 0; _i < array_length(_axes); _i++) {
var _axis = variable_clone(_axes[_i]);
_axis.pressed = false;
global.input_manager_axes[$ _axis.id] = _axis;
}
}
/**
* @function input_get_current_source
* @description Get the current input manager source (keyboard, mouse or gamepad).
* @returns {Real} The current input manager source.
*/
function input_get_current_source() {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
return global.input_manager_current_type;
}
/**
* @function input_get_gamepad_type
* @description Get the current gamepad type (Xinput or DirectInput).
* @returns {Real} The current gamepad type.
*/
function input_get_gamepad_type() {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
return global.input_manager_gamepad_type;
}
/**
* @function input_get_first_connected_gamepad
* @description Get the first connected gamepad.
* @returns {Real} The id of the first connected gamepad.
*/
function input_get_first_connected_gamepad() {
for (var _gamepad_id = 0; _gamepad_id < 8; _gamepad_id++) {
if (gamepad_is_connected(_gamepad_id)) {
return _gamepad_id;
}
}
}
/**
* @function input_update
* @description Update the input manager.
*/
function input_update() {
if (keyboard_check_pressed(vk_anykey) || keyboard_check_released(vk_anykey)) {
global.input_manager_current_type = InputSource.KEYBOARD;
} else if(mouse_check_button_pressed(mb_any) || mouse_check_button_released(mb_any) || window_mouse_get_delta_x() != 0 || window_mouse_get_delta_y() != 0) {
global.input_manager_current_type = InputSource.MOUSE;
} else {
var _num_gamepads = global.input_manager_max_gamepads;
for (var _gamepad_id = 0; _gamepad_id < _num_gamepads; _gamepad_id++) {
if (gamepad_is_connected(_gamepad_id)) {
var _num_buttons = gamepad_button_count(_gamepad_id);
for (var _i = 0; _i < _num_buttons; _i++) {
if (gamepad_button_check_pressed(_gamepad_id, _i)) {
global.input_manager_current_type = InputSource.GAMEPAD;
if(_gamepad_id < 4) {
global.input_manager_gamepad_type = GamepadType.Xinput;
} else {
global.input_manager_gamepad_type = GamepadType.DirectInput;
}
}
}
for (var _i = 0; _i < 6; _i++) {
if (abs(gamepad_axis_value(_gamepad_id, _i)) > global.input_manager_deadzone) {
global.input_manager_current_type = InputSource.GAMEPAD;
if(_gamepad_id < 4) {
global.input_manager_gamepad_type = GamepadType.Xinput;
} else {
global.input_manager_gamepad_type = GamepadType.DirectInput;
}
}
}
}
}
}
//Reset all axes pressed state
var ids = variable_struct_get_names(global.input_manager_axes);
for (var _i = 0; _i < array_length(ids); _i++) {
var _id = ids[_i];
var _axis = global.input_manager_axes[$ _id];
if(_axis.pressed) {
var _axis_value = input_axis(_id);
if (abs(_axis_value) < global.input_manager_deadzone) {
_axis.pressed = false;
}
}
}
}
function input_emit_press(_id) {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
var _binding = global.input_manager_bindings[$ _id];
if (!is_undefined(_binding)) {
var _keyboard = _binding[$ "keyboard"];
if (!is_undefined(_keyboard)) {
for (var _i = 0; _i < array_length(_keyboard); _i++) {
keyboard_key_press(_keyboard[_i]);
}
}
}
}
/**
* @function input_check_pressed
* @description Check if an input was pressed.
* @param {string} _id The id of the input to check.
*/
function input_check_pressed(_id) {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
var _pressed = false;
var _binding = global.input_manager_bindings[$ _id];
if (!is_undefined(_binding)) {
var _keyboard = _binding[$ "keyboard"];
var _gamepad = _binding[$ "gamepad"];
var _gamepad_id = _binding[$ "gamepad_id"];
if (is_undefined(_gamepad_id))
_gamepad_id = input_get_first_connected_gamepad();
var _mouse = _binding[$ "mouse"];
if (!is_undefined(_keyboard)) {
for (var _i = 0; _i < array_length(_keyboard); _i++) {
_pressed |= keyboard_check_pressed(_keyboard[_i]);
}
}
if (!is_undefined(_gamepad) && !is_undefined(_gamepad_id)) {
for (var _i = 0; _i < array_length(_gamepad); _i++) {
_pressed |= gamepad_button_check_pressed(_gamepad_id, _gamepad[_i]);
}
}
if (!is_undefined(_mouse)) {
for (var _i = 0; _i < array_length(_mouse); _i++) {
_pressed |= mouse_check_button_pressed(_mouse[_i]);
}
}
}
return _pressed;
}
function input_axis_pressed(_id, _positive) {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
var _pressed = false;
var _axis = global.input_manager_axes[$ _id];
if (!is_undefined(_axis)) {
var _axis_value = input_axis(_id);
if(!_axis.pressed) {
if (_positive) {
if(_axis_value > global.input_manager_presszone) {
_pressed = true;
_axis.pressed = true;
}
} else if ( _axis_value < -global.input_manager_presszone) {
_pressed = true;
_axis.pressed = true;
}
}
}
return _pressed;
}
/**
* @function input_check
* @description Check if an input is being held.
* @param {string} _id The _id of the input to check.
*/
function input_check(_id) {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
var _held = false;
var _binding = global.input_manager_bindings[$ _id];
if (!is_undefined(_binding)) {
var _keyboard = _binding[$ "keyboard"];
var _gamepad = _binding[$ "gamepad"];
var _gamepad_id = _binding[$ "gamepad_id"];
if (is_undefined(_gamepad_id))
_gamepad_id = input_get_first_connected_gamepad();
var _mouse = _binding[$ "mouse"];
if (!is_undefined(_keyboard)) {
for (var _i = 0; _i < array_length(_keyboard); _i++) {
_held |= keyboard_check(_keyboard[_i]);
}
}
if (!is_undefined(_gamepad) && !is_undefined(_gamepad_id)) {
for (var _i = 0; _i < array_length(_gamepad); _i++) {
_held |= gamepad_button_check(_gamepad_id, _gamepad[_i]);
}
}
if (!is_undefined(_mouse)) {
for (var _i = 0; _i < array_length(_mouse); _i++) {
_held |= mouse_check_button(_mouse[_i]);
}
}
}
return _held;
}
/**
* @function input_check_released
* @description Check if an input was released.
* @param {string} _id The id of the input to check
*/
function input_check_released(_id) {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
var _released = false;
var _binding = global.input_manager_bindings[$ _id];
if (!is_undefined(_binding)) {
var _keyboard = _binding[$ "keyboard"];
var _gamepad = _binding[$ "gamepad"];
var _gamepad_id = _binding[$ "gamepad_id"];
if (is_undefined(_gamepad_id))
_gamepad_id = input_get_first_connected_gamepad();
var _mouse = _binding[$ "mouse"];
if (!is_undefined(_keyboard)) {
for (var _i = 0; _i < array_length(_keyboard); _i++) {
_released |= keyboard_check_released(_keyboard[_i]);
}
}
if (!is_undefined(_gamepad) && !is_undefined(_gamepad_id)) {
for (var _i = 0; _i < array_length(_gamepad); _i++) {
_released |= gamepad_button_check_released(_gamepad_id, _gamepad[_i]);
}
}
if (!is_undefined(_mouse)) {
for (var _i = 0; _i < array_length(_mouse); _i++) {
_released |= mouse_check_button_released(mouse[_i]);
}
}
}
return _released;
}
/**
* @function input_axis
* @description Get the value of an axis.
* @param {string} _id The id of the axis.
*/
function input_axis(_id) {
if(instance_number(obj_input_manager) == 0) {
instance_create_depth(0, 0, 0, obj_input_manager);
}
var _axis_value = 0;
var _axes = global.input_manager_axes[$ _id];
if (!is_undefined(_axes)) {
var _keyboard = _axes[$ "keyboard"];
var _mouse_movement = _axes[$ "mouse_movement"];
var _gamepad = _axes[$ "gamepad"];
var _gamepad_id = _axes[$ "gamepad_id"];
var _gamepad_axis = _axes[$ "gamepad_axis"];
if (is_undefined(_gamepad_id))
_gamepad_id = input_get_first_connected_gamepad();
if (!is_undefined(_keyboard)) {
var _negative = _keyboard[$ "negative"];
for (var _i = 0; _i < array_length(_negative); _i++) {
_axis_value -= keyboard_check(_negative[_i]);
}
var _positive = _keyboard[$ "positive"];
for (var _i = 0; _i < array_length(_positive); _i++) {
_axis_value += keyboard_check(_positive[_i]);
}
}
if (!is_undefined(_mouse_movement)) {
if (_mouse_movement == "horizontal") {
_axis_value += window_mouse_get_delta_x();
} else {
_axis_value += window_mouse_get_delta_y();
}
}
if (!is_undefined(_gamepad) && !is_undefined(_gamepad_id)) {
var _negative = _gamepad[$ "negative"];
for (var _i = 0; _i < array_length(_negative); _i++) {
_axis_value -= gamepad_button_check(_gamepad_id, _negative[_i]);
}
var _positive = _gamepad[$ "positive"];
for (var _i = 0; _i < array_length(_positive); _i++) {
_axis_value += gamepad_button_check(_gamepad_id, _positive[_i]);
}
}
if (!is_undefined(_gamepad_axis) && !is_undefined(_gamepad_id)) {
_axis_value += gamepad_axis_value(_gamepad_id, _gamepad_axis);
}
}
if (abs(_axis_value) < global.input_manager_deadzone)
_axis_value = 0;
return clamp(_axis_value, -1, 1);
}
@adriano-t

adriano-t commented Sep 20, 2024 •

Copy link
Copy Markdown
Author

How to use

create an object obj_input_manager

Initialization

Create event of obj_input_manager

enum Action {
    jump,
    shoot,
    move
}

bindings = [
    {
        "id": Action.jump,
        "keyboard": [
            vk_space,
            vk_up,
        ],
        "gamepad": [
            gp_face1
        ],
    },
    {
        "id": Action.shoot,
        "mouse": [
            mb_left
        ],
        "gamepad": [
            gp_shoulderr,
            gp_shoulderrb,
        ],
    },
];

axes = [
    {
        "id": Action.move,
        "keyboard": {
            "negative": [
                vk_left, 
                ord("A")
            ],
            "positive": [
                vk_right, 
                ord("D")
            ],
        },
        "gamepad": {
            "negative": [gp_padl],
            "positive": [gp_padr],
        },
        "gamepad_axis": gp_axislh,
    }
]

input_setup(bindings, axes);

BEGIN STEP EVENT of obj_input_manager

input_update()

Usage

//Step event obj_player

var axis = input_axis(Action.move)
x += axis * 10;


if (input_check_pressed(Action.jump)) {
    vspeed = -10;
}

@adriano-t

Copy link
Copy Markdown
Author

@davidescarioni I merged your changes to the code above and deleted the outdated code, thanks!

@davidescarioni

Copy link
Copy Markdown

Feather put a warning on line 45: Type 'Real' differs from type 'String' specified in jsdoc

@davidescarioni

Copy link
Copy Markdown

I hadn't tested the script yet after your latest update, but now I'm getting this error:
input_manager at line 147 : enum reference 'ui_ver' does not exist in 'Action'

Also, it is possible to use the script without using the axis binding?

@adriano-t

Copy link
Copy Markdown
Author

I hadn't tested the script yet after your latest update, but now I'm getting this error: input_manager at line 147 : enum reference 'ui_ver' does not exist in 'Action'

Also, it is possible to use the script without using the axis binding?

Fixed, thank you!

@davidescarioni

Copy link
Copy Markdown

It seems it isn't fixed in the script above πŸ˜…

@adriano-t

Copy link
Copy Markdown
Author

It seems it isn't fixed in the script above πŸ˜…

whoops, i removed the debug line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment