Binding KeyCode.ButtonL1/ButtonR1 through ContextActionService not possible with Backpack CoreGui

Description: ContextActionService:BindAction(...) does not behave consistently when binding to input types KeyCode.ButtonL1 and KeyCode.ButtonL2 while the Backpack CoreGui is enabled. Binding to other inputs used by the Backpack CoreGui, such as KeyCode.One, is possible while the aforementioned inputs is not.

Repro steps: A compatible gamepad controller is required; this issue was found using XBox One Wireless Controller. Open a new place in ROBLOX Studio and hit Play Solo. Run this in the Command Bar:
game:GetService("ContextActionService"):BindAction("X", print, false, Enum.KeyCode.ButtonL1)
Press the Left Bumper (L1) on your controller. The same steps can be done using ButtonR1 (Right Bumper).

Expected behavior: This code is expected to send this message to the Output window when Left Bumper (L1) is pressed:
X Enum.UserInputState.Begin InputObject

Actual behavior: The message is not printed.

Work-around: If you disable the Backpack CoreGui, the binding works again. This code will allow ButtonL1 and ButtonR1 to be bound properly:
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
Disabling the Backpack CoreGui will fix bindings retroactively (bindings before the previous line is called).

Misc. details: I found this issue while messing around with gamepad controls. I was making a free-looking camera script that allowed the user to move the camera anywhere they wanted. When I wanted to create a binding to L1, I noticed it wasn’t working. I wasn’t using the default humanoid. I cross-checked this with @Maelstronomer and he verified the bug and realized that the Backpack may be causing it.

1 Like

TL;DR: Backpack coregui is stealing ButtonR1 and ButtonL1 while backpack is enabled (no other buttons have this weirdness)

1 Like

I remember seeing this when the gamepad scripts were first written, but I wasn’t doing enough with CAS to take issue with it.

Can’t you first unbind the buttons so they’re available for your scripts?
It might also be the backpack (unregisters and) registers them after your scripts, “stealing” them.

@einsteinK

(at the bottom, “What happens the moment I bind an input that is already bound?”)

Expected behaviour to be sending .Cancel to the backpack coregui script.

We were using the command bar in solo so waiting didn’t matter in this case (it does matter if you’re initializing a script when they first spawn, though.)
game:GetService("ContextActionService"):BindAction("test", print, false, Enum.KeyCode.ButtonR1)
Doesn’t print, even with all PlayerScripts replaced with blank scripts. Tried in new instances each time. Non-bumpers printed.

CoreGui’s use BindCoreAction, which override all other bindings (so you don’t get weird behavior in the menu and what not). It does seem like we can unbind these buttons in the backpack script though when there isn’t anything in the backpack… I’ll look into this.

1 Like

Thanks. So for a guideline to us devs: it is in fact good practice to unbind any actions which will have no effect?

yes, but you can’t unbind core actions, unless you have a core script, which I really hope no one does :smile: Also, if your game doesn’t need to use the backpack I would just disable it.

1 Like

i’m making a fighting game and i want players to be able to block whenever pressing ButtonR1 while having a tool equipped. after reading this post’s comments i assume it’s not possible?