Godot: Add Input Axes to complement Input Actions

Created on 10 Dec 2017  路  7Comments  路  Source: godotengine/godot

The Problem: As it stands, to set up a simple four-way movement scheme, you need to bind four actions in the InputMap - one for each direction, - and if you want to have proportional input (gamepad axes, etc.), you need to roll your own input axis mapping and polling code - for each script that needs it! This is tedious and non-extensible and, in my opinion, needs a better way of doing it.

The Solution: The proposed solution is to extend the InputMap system to allow binding Axes as well as actions. Similar to Unreal Engine's implementation, the InputAxis will allow binding a raw axis, or a set of keys or buttons with a constant axis value (e.g. axis_move:KEY_A = -1.0, axis_move:KEY_D = 1.0, etc.); allowing an axis to be controlled with a joystick, keyboard, or mouse as required.

This solution would also make trivial axis rebinding, as changing an axis is as simple as a call to InputMap::axis_add/remove_event.

The Implementation: Implementation of this feature would require three major parts:

  • Add InputMap::Axis, code in InputMap for working with said axes, and related functionality (InputEventAxis, Input::get_input_axis_value, etc.)
  • Extend the input event dispatching code to handle Axis Events
  • Extend the editor's Input Map section to support viewing and binding axes.

Questions, comments, etc? I've done some poking around in the code and it looks pretty straightforward to implement, so if there's no objections, I should have an initial PR in a few weeks.

archived feature proposal core

Most helpful comment

A feature like that is specific enough that it is probably better implemented in application-specific code, though you are welcome to open a separate issue. What I am proposing is a simple and centralized abstraction, allowing for transparent key and axis re-binding as well as simplification of input control code.

All 7 comments

Would be cool if you could explain for people who never used unreal, how this proposal differentiate from what we have currently:
axis

and how we can improve current system?

I think that one big issue with the current system is that you need to bind for each device, if i got it correctly. If you want to do a local multiplayer, you need to bind joy one by one. Unreal has an interesting way to handle input with "player controllers", objects that recive input related to one player and can "possess" pawns.

Will post a screenshot later when I get back to my rig.

The way Unreal Engine works is it has two input binding schemes: Actions and Axes. Actions are similar to Godot's, being a binary-state 'virtual button', either on or off. Axes are proportional inputs, ranging from -1 to 1, allowing binding gamepad sticks, etc with no loss of precision.

Currently, you can only bind one half of a gamepad's axis at a time in Godot, and only (AFAIK), as a binary input (is_action_pressed, etc). If you want to listen to a full axis, you have to write your own code for this, defeating the point of the InputMap architecture.

Binding devices for local multiplayer is outside the scope of this feature proposal, but you are welcome to open another if you have an idea of how to go about it.

I don't know how Unreal handles axis, but I already tried to do a class working a bit like Unity's Axis. This one can be pretty good for motion because, when pressing a key bind to an axis, you can setup the axis to have a speed and a gravity : when the key is pressed, the axis value will increase based on the speed, and when the key is released the axis goes back to 0 based on the gravity.This allow a more precise way for movement than just constant -1, 0, 1 with keys. The same effect can be used with gamepad's axis when the game needs a bit of precision but not too much to need a precise control of the joystick.

A feature like that is specific enough that it is probably better implemented in application-specific code, though you are welcome to open a separate issue. What I am proposing is a simple and centralized abstraction, allowing for transparent key and axis re-binding as well as simplification of input control code.

To further explain why this feature is useful and what features it could have, here's a screenshot and explanation of the Input axis system in Unity:

inputaxis

Unlike Godot's inputs, which are true or false, Unity's Input axis system returns a float between -1 and 1, allowing one variable for in-game axis behavior (instead of moving left or right depending on booleans, you can move horizontally and multiply by the axis variable).

The behavior of an axis can also be adjusted with options such as gravity. An input can be set to either instantly jump between 0 and 1, for a behavior similar to booleans, or spend some time in-between. For simple character movement, where you can define moving forward/backward and left/right, a gradual transition between 0 and 1 or -1 makes the character movement VASTLY smoother. In real life, there is no instantaneous acceleration.

Furthermore, I currently can't use the Input class to get mouse movement. Input can currently only bind mouse buttons, and mouse movement can't be translated to simple booleans. This is a serious oversight for any games that wish to get input from mouse movement.

Closed in favor of Godot's new Strength system.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Angluca picture Angluca  路  100Comments

blurymind picture blurymind  路  192Comments

karroffel picture karroffel  路  144Comments

ghost picture ghost  路  105Comments

nunodonato picture nunodonato  路  143Comments