Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow getting Input "axis" values by specifying multiple actions #519

Closed
aaronfranke opened this issue Feb 25, 2020 · 3 comments · Fixed by godotengine/godot#42976
Closed
Milestone

Comments

@aaronfranke
Copy link
Member

Describe the project you are working on:

Godot demo projects

Describe the problem or limitation you are having in your project:

It's not really a limitation, just an annoyance. In any game involving movement, including many of the demo projects, it's really common to see code like this (from TPS demo):

var motion_target = Vector2(Input.get_action_strength("move_right") - Input.get_action_strength("move_left"), 
			    Input.get_action_strength("move_back") - Input.get_action_strength("move_forward"))

Describe the feature / enhancement and how it helps to overcome the problem or limitation:

The above example is a bit cluttered and repetitive. So, what can we do to fix it? I propose we add a new method called get_axis (or possibly get_axis_strength) which allow us to do this instead:

# Order of get_axis is positive action, negative action.
var motion_target = Vector2(Input.get_axis("move_right", "move_left"), 
			    Input.get_axis("move_back", "move_forward"))

We could also expand this to allow working with two axes at once, perhaps get_vector:

# Order of get_vector is positive x, negative x, positive y, negative y.
var motion_target = Input.get_vector("move_right", "move_left", "move_back", "move_forward")

Bonus idea: This could also be expanded by allowing arrays to be accepted:

var movement_actions = ["move_right", "move_left", "move_back", "move_forward"]
var motion_target = Input.get_vector(movement_actions)

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

Importantly, this proposal does not involve Input having any kind of internal concept of what an axis is. You can provide any two actions, and it will simply give the result of one's strength minus the other's strength. You could even create nonsense like Input.get_axis("ui_accept", "ui_up")) if you wanted to, since it just accepts any set of actions.

Because of this simplicity, the implementation would probably only involve a few self-contained functions, each of which should be fairly small.

If this enhancement will not be used often, can it be worked around with a few lines of script?:

Yes, it can be worked around with a few lines of script. But also, it will be used often, as any game that involves player movement will likely have code that looks like this.

Is there a reason why this should be core and not an add-on in the asset library?:

It's too simple of a proposal to have an add-on in the asset library just for it.

@groud
Copy link
Member

groud commented Feb 25, 2020

The problem with such approach is handling the deadzones. Usually, when you get an axis, you expect the deadzone to be the same for each side. And when you get a vector, you want the deadzone to be a circle, not a square.

This means computing a deadzone value out of the underlying actions' deadzone (like an average), or layering another deadzone on the strength produced but the underlying events, or even or eventually distort the deadzone area per side. Even if the last one is probably the most easy to understand, I fear the deadzone thing might lead to confusing behaviors.

We have to make sure this is not a problem.

Other than that, since it does not modify the underlying system, and is only about adding two helper functions used often, I don't mind the addition.

@Xrayez
Copy link
Contributor

Xrayez commented Feb 25, 2020

Yep, I usually define this kind of utility method:

static func get_motion():
	var left  = -Input.get_action_strength("move_left")
	var right = +Input.get_action_strength("move_right")
	var up    = -Input.get_action_strength("move_up")
	var down  = +Input.get_action_strength("move_down")

	return Vector2(left + right, up + down)

@aaronfranke
Copy link
Member Author

@groud I agree that there are further ways to improve get_vector, I'm curious how complicated that would be to implement (is there a way inside Input to get the raw value and bypass the deadzone so that we can apply a deadzone ourselves?), but the deadzone really shouldn't matter for get_axis since on joysticks you can only push one direction at a time and for keyboards it's always 0 or 1.

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

Successfully merging a pull request may close this issue.

4 participants