godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.82k stars 20.94k forks source link

_UnhandledInput @event.IsActionPressed() is not capturing continuous input #93425

Open lessthen3 opened 3 months ago

lessthen3 commented 3 months ago

Tested versions

-Only tested on version 4.2.2.stable.mono -Tested on two seperate computers

System information

Windows 10 Version10.0.19045 Build 19045, Processor AMD Ryzen 9 5950X 16-Core Processor, 3401 Mhz, 16 Core(s), 32 Logical Processor(s), RTX 3060 TI, Forward+

Issue description

Im trying to create a mechanic where a stat is charged by holding down a button for a set period of time.

I can get the feature implemented using the Input singleton, however for some reason I just cannot get it to work with _UnhandledInput(). This problem persists across my dektop and laptop, and two seperate Godot projects.

Currently if I use the @event passed through _UnhandledInput() and i use the IsActionPressed() function, the continuous input of holding down a button is not registered. Although if I use the Input singleton and do Input.IsActionPressed(), then I achieve the desired result despite the functions seeming like they should do the same thing. (from what i've been able to gather from the documentation and forums)

Intended output from the Input.IsActionPressed() implementation:

issue correct output cropped

Incorrect output produced from using @event from _UnhandledInput()

issue incorrect output cropped

Steps to reproduce

-Start project and run the scene -Click anywhere on the window -Done! You should see the output printed to console

Minimal reproduction project (MRP)

2D MRP Godot 2024-06-21.zip

bs-mwoerner commented 3 months ago

To do something repeatedly while a condition is met, you can use a time-based approach via a timer or _PhysicsProcess() where you check the current state of the mouse button via the Input singleton.

lessthen3 commented 3 months ago

That's what i originally thought, however I tried changing the key action to "Key_J"(in my project settings) which is mapped to the 'J' key, and it still produces the same result.

I originally used the Input singleton, but that is simply not an option if i have GUI elements.

I have tried setting 'allowEcho = true', but I am still getting the same result.

Is there any way for me to handle my GUI input and player input seperately? It is a must have for my project.

bs-mwoerner commented 3 months ago

You can do something like this and get repeated 'ui_accept' prints when holding down the Enter key:

func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("ui_accept", true):
        print('ui_accept')

This will still not repeat for mouse or gamepad buttons, though.

I don't know your particular use case, but the general advice is to process non-GUI input in _unhandled_input, so that it can be overridden by GUI controls. Depending on the type of game, it's also very common to handle player input in _process or _physics_process.