Godot Version
v4.5.1.stable.mono.official [f62fdbde1]
Question
I’m trying to fully understand the input system and made a small example with re-binding support, but there’s a rather annoying issue I’m facing. As soon as I re-bind one of my controls, the last @event seems to get stuck as being pressed until I press it again.
Some relevant code, when the player presses a button that shows one of the Input events, I spawn a small scene that catches all input events and processes it, as such:
using Godot;
using NathanHoad;
using CommandPatternExample.Models;
namespace CommandPatternExample.UI;
public partial class ChangeBindingUi : CanvasLayer
{
public ButtonBinding BindingToChange;
public BindingButton ParentToNotify;
public override void _Input(InputEvent @event)
{
base._Input(@event);
if (@event.IsActionPressed("ui_cancel")
|| @event is InputEventJoypadButton { ButtonIndex: JoyButton.Start, Pressed: true })
{
QueueFree();
return;
}
switch (@event)
{
case InputEventJoypadMotion or InputEventJoypadButton when BindingToChange.IsController:
InputHelper.ReplaceJoypadInputForAction(BindingToChange.ActionName,
BindingToChange.EventForAction, @event);
QueueFree();
break;
case InputEventKey key when !BindingToChange.IsController:
InputHelper.ReplaceKeyboardInputForAction(BindingToChange.ActionName,
BindingToChange.EventForAction, key);
QueueFree();
break;
}
}
public override void _ExitTree()
{
ParentToNotify.FinishedRebinding();
base._ExitTree();
}
}
But, as I said, when I switch one of the bindings out, that last input key will never get released, and Godot will think I’m constantly pressing it. Am I missing a step here to “release” the input after I catch it?
It’s probably not necessary, but here’s the code where I actually handle movement of my simple player:
public override void _Process(double delta)
{
base._Process(delta);
if (!_initialized)
{
return;
}
foreach (KeyValuePair<StringName, ICommand> kv in _bindings)
{
if (Input.IsActionPressed(kv.Key))
{
kv.Value.Execute(delta);
}
}
}