Input keys grouping

Godot Version

4.1.3 stable

Question

Is it possible to group input keys? I have:

and I want to create condition if Input.is_action_just_released($MOVE_KEYS$), but didn’t find how to group. ChadGPT said that I could write condition for each case, but I’m not statisfied about that. Of course I can use match as a relatively short way, but all body code will be similar and I don’t like it.

var movement_actions = [
	"move_right",
	"move_left",
	"move_up",
	"move_down",
]

func is_movement_released() -> bool:
	for action in movement_actions:
		if Input.is_action_just_released(action):
			return true
	return false

Another approach might be to programmatically adjust actions using the InputMap singleton.

You could add a move action, then have an autoload script loop through move_right, move_up, etc, and at startup and add all the events assigned to those to the move action as well. So then for example the D key would be considered both a move_right and a move action.

A little more complicated to set up, but you’d only need to loop through the move actions once at startup instead of every time you wanted to check the action, and you could check for the move action the same way you would for any other.

1 Like

God, I don’t imagine how it will be, I’m rookie in Godot. And this is complicated for my problem, I think: my player enters Idle state for a milisecond when changing y axis or x axis direction. Maybe not, but I’m really don’t imagine how it will be looks like. But I’ll remember, thanks.

Good point, but what about performance? I need this algorithm to correct animation issue which lasts literally one delta.

you don’t need to , just use

var vec = Input.get_vector("move_right","move_left","move_up","move_down")

if vec not Vector.zero,it means have move input.

You can press left and right keys on a keyboard at the same time, which results in a zero vector.

This is literraly same algorithm as I have now.

func Update(_delta):
	if  _player_vector() == Vector2.ZERO:
		print("Move change to Idle")
		Transitioned.emit(self, "idle")

func Physics_Update(_delta):
	if player:
		_player_move_velocity()

The problem is - when I trying to move left-right constantly, during a change vector from -1 to 1 and vice versa, there is a little window, when velocity becomes ZERO:

image

That what I’m trying to manage.

This is the last thing, I don’t want to optimise my test project to full game. I’ve been sitting in one place for so long with state machine.

Ok I’m starting to understand what you’re trying to do a bit better, I don’t think checking for inputs will give you what you want. Say the player is holding down the W key to move up, then they decide to turn right and press the D key and release the W key. They haven’t stopped moving but that input action release is going to fire when they release the W key. I think checking the player velocity is a better approach, that won’t confuse changing directions with actually stopping.

Will try today, good point. But I’m afraid that won’t solve my problem, because velocity also become zero while turning.

There was a really similar case on Reddit recently: https://www.reddit.com/r/godot/comments/18ti3mj/how_to_avoid_going_into_the_idle_state_when/

Check both, input and velocity vectors.

Thanks, I thought about it when replying previously. I need to check it in fact, because:

Well, your coundition really works. I forgot that a vector is still equal to one when player changes direction, thanks!

Idle physics updated: (-8, 0)	(1, 0)
Idle physics updated: (0, 0)	(1, 0)
Idle physics updated: (8, 0)	(1, 0)

Continuing the discussion from Input keys grouping:

I think you need to differentiate between input and movement.
The player’s input_vector being 0 doesn’t mean the character’s velocity is 0.
When I make a character state machine, I use velocity being 0 as the condition to transition to idle, not input_vector.

Of course, if you want your character to run in the direction of a wall, then you do need to use input as the condition to transition states.

But I can tell you that many game characters are stuck to the wall and still playing the running animation, when in reality they’re just running in the animation, but their actual status is still idle.

if  _player_vector() == Vector2.ZERO and player.velocity == Vector2.ZERO:
		print("Move change to Idle")
		Transitioned.emit(self, "idle")

I did it like this and it’s works properly.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.