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

InputEvent get_action() if is_action_type() true #9408

Closed
artvel opened this issue Mar 29, 2024 · 16 comments
Closed

InputEvent get_action() if is_action_type() true #9408

artvel opened this issue Mar 29, 2024 · 16 comments

Comments

@artvel
Copy link

artvel commented Mar 29, 2024

Describe the project you are working on

Trying to build an in-game ui that includes pieces like windows and other elements that can be bound to input actions.

Describe the problem or limitation you are having in your project

The problem right now is that it is not possible to get the action name from the InputEvent therefore I have to go through all the ui elements with actions to check if one of them could be a match with the is_action..() methods. The current state is very inefficient and doesn't allow to build dynamic action related ui's.

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

If it was possible to get the action after the check that already exists event.is_action_type(), it would be possible to also structure action elements with a prefix like window_inventory and if the action doesn't begin with window_ don't do any further checks on that matter like now.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Example:

func _input(event:InputEvent) -> void:
	if event.is_action_type():
           var aevent:InputEventAction = event as InputEventAction
           if aevent.action.begins_with("window_"):
              # do window related things ..
              # track the correct window by the action name
              # do the execution on the window, inventory or whatever

I know that InputEventAction wasn't built for this exact purpose but maybe its not that hard to change it to this without breaking other edges.
If there is a more efficient way to make it possible to read the action I would go for that instead of the proposal.

Look at the proposal as demand for the action to be read from the InputEvent if it contains one.

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

It will be used often that is certain. While researching about this issue I saw that there are a lot of people on reddit or other forums asking for how to get the action name for dynamic purposes.

The workaround is ugly and inefficient as I mentioned in the problem section. You have to go through all the list(s) and match it against the is_action... methods during an input event.

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

Yes, because input is core.

@AThousandShips
Copy link
Member

I'm not following here, what do you mean by:

If it was possible to get the action:String

You can get this property, but what are you asking for specifically? That it would be type safe? What's wrong with the example code you gave?

@artvel
Copy link
Author

artvel commented Mar 29, 2024

No, I mean it can also be a StringName. The only thing I would like is to have a way to access the action.

@AThousandShips
Copy link
Member

AThousandShips commented Mar 29, 2024

Yes you can, what are you unable to do?

@artvel
Copy link
Author

artvel commented Mar 29, 2024

So I would have to do this, right?

func _input(event:InputEvent) -> void:
    var ev = InputEventAction.new()
    ev.action = "window_inventory"
    ev.pressed = true
    Input.parse_input_event(ev)

@AThousandShips
Copy link
Member

Oh yes that's true, sorry you were not clear that you weren't talking about input actions being fired :) I assumed you meant when you actually got those

Input doesn't handle actions directly, so you are supposed to use the is_action methods, and the same key can map to multiple actions, so it wouldn't make sense to have this solution

@artvel
Copy link
Author

artvel commented Mar 29, 2024

Yeah, the InputEventAction was just meant to be used for creating an event from gdscript. But yes, I am looking for a way to read the action for when the inputs are being fired.

@AThousandShips
Copy link
Member

You can't, because it doesn't work that way, there isn't an action, there could be many, or none

@artvel
Copy link
Author

artvel commented Mar 29, 2024

But there is this method is_action_type() in the InputEvent? If the method returns true is what you are saying still the case that there could be many or none?

@AThousandShips
Copy link
Member

AThousandShips commented Mar 29, 2024

No, that just means it's an InputEventAction or can be an action, see the documentation

@artvel
Copy link
Author

artvel commented Mar 29, 2024

That sounds about right. With that in mind, why can't it be possible to access the action after that check? Or more accurate an array of actions as there can be many..

@AThousandShips
Copy link
Member

AThousandShips commented Mar 29, 2024

How? What action? How would you find an action? Would it only return if there was exactly one? How would this be checked? Also there's fuzzy actions which means you can partially match them?

What would be better about this than using the method designed to do this?

@artvel
Copy link
Author

artvel commented Mar 29, 2024

Well, I described that already above. Currently I need to go through a list of elements that are bound to an action in any case to check if there is a match on one.
Can't find any information about fuzzy actions. Could you provide more information about that?

@AThousandShips
Copy link
Member

AThousandShips commented Mar 29, 2024

And you would have to do that if it returned an action as well, you'd need to check all those returned values, it would be very inefficient compared to just checking against them

I think this is a case of you not having a setup that's efficient, why not just create an array of StringName action names and iterate over it and check them? But it sounds odd that you'd be checking against a list, why not just have specific checks and do the relevant action?

To me it sounds strange to have a "react on any of these actions", just have "if X, do A, if Y do B"?

Fuzzy actions is the exact_match part of is_action, see there

Your use case doesn't sound like a normal use case, so it isn't necessarily going to be supported by the engine

@artvel
Copy link
Author

artvel commented Mar 29, 2024

Well, I am already doing the check with the list. But if the action would be accessible I could avoid some checks but you're kinda right, it wouldn't make a huge difference in terms of performance as there would still be checks after every input event.

The best solution would be to introduce signals related to actions.
This way we could just connect to an input-signal-action and prevent from any runtime checks but instead execute directly the corresponding code.

@AThousandShips
Copy link
Member

There's a proposal for just that:

@artvel
Copy link
Author

artvel commented Mar 29, 2024

Okay, cool. Thanks @AThousandShips for everything!

@artvel artvel closed this as not planned Won't fix, can't repro, duplicate, stale Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants