unhandled_input is not handling some input

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Godont

I have a canon which I wish to charge when the player holds the “shoot” button, and fire when the button is released. Following the official documentation recommendations, I handle all gameplay input in the _unhandled_input function:

var canon_charging = false
var canon_fired = false

func _unhandled_input(event):
canon_fired = false
	if(event.is_action_pressed("shoot")):
		canon_charging = true
	elif event.is_action_released("shoot"):
		if canon_charging:
			canon_fired = true
		canon_charging = false

func _physics_process(delta):
    if canon_charging:
    	charge_canon()

	if canon_fired:
    	shoot()

This all works fine, but sometimes releasing the “shoot” button doesn’t cause the player to shoot, and instead the player is stuck on the charging animation. Through print statements to the log I’ve traced the issue to the check in _unhandled_input for whether the button is released.

Is this a known issue? I thought that the _unhandled_input function would catch all input events that have not yet been consumed, which for me is all of them since I have not implemented any other input functions yet. If it is known, are there fixes planned?

EDIT

This problem is mostly solved for me, but for future readers I’ll describe a few things which I was affected by that can contribute to this issue.

  1. My old MadCatz Xbox controller is decent, but it seems as though some buttons stick sometimes. I tried switching to a switch controller, but that presented its own issues which I won’t go into because they aren’t relevant here. Takeaway: be sure the controller is in tip-top shape.

  2. My version of Godot isn’t the most up-to-date, and updating did give different behaviour (the minimal example can be downloaded from here if anyone wants to try).

  3. The most serious issue was a logic error which I’ll explain. In the _unhandled_input I was initializing the canon_fired boolean to false and only changing it to true if the “shoot” button was released (then handling the logic for shooting in the physics process). Normally this would work, but not if another input is captured before the physics process has a chance to run (i.e., such as analog stick input).

    I believe this is what was occurring. Moving the analog stick around while releasing the button caused canon_fired to be set to false again before the physics process could run and call shoot. However, newer versions of Godot seem like they may call _physics_process more frequently, and so they yield different behaviour.

The fix is quite simple: the `canon_fired` variable is now set to `false` inside the `shoot` function (which is better practice anyway) and the result works with both versions of Godot.

I hope this helps anyone who may have run into a similar set of circumstances/made similar errors to me :slight_smile:

:bust_in_silhouette: Reply From: yrtv

Make sure your input is not set as handled somewhere in the scene before it received by the node.

Edit:
To be clear “You have not implemented” does not mean event was not consumed by some node. Some nodes can process input in their c++ code.

Yeah I’m sure: there is currently one node in the entire game handling input, and this is all the code in it relating to the “shoot” button. It works most of the time, but every now and then it randomly doesn’t shoot

Godont | 2021-02-09 16:59

Oh, I see your edit, sorry I didn’t know the input events might be getting intercepted/handled by the underlying C++ code.

Is there any way I can check where it might be getting handled? I don’t know much about the underlying code.

Godont | 2021-02-09 18:02

Looks like only Control can consume InputEvent before _unhandled_input

Control — Godot Engine (stable) documentation in English

If your Input Device(Mouse, Keyboard, Game pad, Touchscreen) is not buggy and your node is not one of Control nodes, then it’s a bug.

Bugs are reported here: Issues · godotengine/godot · GitHub

yrtv | 2021-02-09 19:32

Saying “If your Input Device is not buggy” helped me a lot. I’ve been using the B button on my ancient MadCatz Xbox controller for the “shoot” action. When I made a minimal project to upload to the repository I added the space bar to the input map. The issue would occur now and then with the controller, but never with the space bar.

Looks like I’ve got a bad controller. I wanted to test with my newer switch controller to be sure it isn’t an issue with controllers in general, but apparently my cpu doesn’t have a bluetooth receiver. I’ve ordered one which should be here in a few days, at which point I’ll conduct the test with my switch controller and update here, but for now I think the root cause is likely identified.

Thanks!

Godont | 2021-02-09 20:55