I am trying to make a keybind menu where you can set your keybinds, but the issue is that while you’re setting your keybinds your inputs can still be recorded by the game, which leads to issues like this.
As you can see in the video, the menu disables when i try to set a move to the LMB button. I do not want this.
I get the input for the keybind using UIS.InputBegan:Wait().
How would I make the input that is passed by this event be unprocessed by the game, and if i can’t do that, how would I go about remaking this system so that it would be possible?
If you are making keybinds you can use the ContextActionService:BindActiomAtPriority() to bind an action with a priority level which stops other input from firing. Or you can manually have a Bound action sink or pass input if they use the same 'evel
Also the bool gameProcessedEvent for UserInputService does the opposite where it detects if an action is bound or if the game has already processed the input. This makes sure input is not detected twice by two different actions/events.
For this case I think you will be needing the first one.
How would I have the game recognize what input is made if I use ContextActionService? Is there anyway to have it return the key that was pressed? I use UIS.InputBegan:Wait() to find out what the player clicked, is there a better way to detect this?
You can use UserInputService.InputBegan:Wait() and then set your default ContextActionService Keybinds.
Something like this
local Camera = workspace.CurrentCamera
local Player = game:GetService("Players").LocalPlayer
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")
-- Method 1
local BoundAction = "Action1" -- Action Name. We will print this action for the action
local function ActionHandler(actionName: string, inputState: Enum.UserInputState, inputObject: InputObject)
if inputState ~= Enum.UserInputState.Begin then
return Enum.ContextActionResult.Pass -- Pass action if we are not interested in taking input
end
if actionName == "Action1" then
print("Did:",actionName) -- This will be our "action" code in here
return Enum.ContextActionResult.Sink -- Sink as input has been processed
elseif actionName == "ChangeKeybind" then
local ValidKey = false -- You don't have to do it this way however I just did some simple checking for valid keybinds and have a flag for valid keybind
ContextActionService:UnbindAction(actionName) -- Unbind action temporarily whilst we are processing it so we don't get "double" inputs
repeat
local input: InputObject, gameProcessedEvent: boolean = UserInputService.InputBegan:Wait()
if input.KeyCode and not gameProcessedEvent and input.KeyCode ~= inputObject.KeyCode then -- If input is a key and not already bound
ValidKey = true
print("Valid input.")
-- Now we have a new Keycode we can unbind the action and then rebind it
ContextActionService:UnbindAction(BoundAction)
ContextActionService:BindActionAtPriority( -- Bind the action(again)
BoundAction,
ActionHandler,
false,
Enum.ContextActionPriority.Medium.Value, -- Remember we want our normal bound actions to be low so that when we want to bind them we can set that to high.
input.KeyCode
)
print("Changed keybind for:",BoundAction,"to",input.KeyCode)
else
warn("Invalid input. Please try again.")
end
until ValidKey == true -- there is a case where the keybind could be the resseting keybind but if you are using GUIs as the button to reset the keybind it won't matter.
ContextActionService:BindActionAtPriority(
"ChangeKeybind",
ActionHandler,
false,
Enum.ContextActionPriority.High.Value,
Enum.KeyCode.Space
) -- How we can re enable out keybind
return Enum.ContextActionResult.Sink -- Sink input as we have processed it
end
end
ContextActionService:BindActionAtPriority( -- Bind the action
BoundAction,
ActionHandler,
false,
Enum.ContextActionPriority.Medium.Value, -- Or you can set this one to have medium and the "changekeybind" to high.
Enum.KeyCode.T
)
ContextActionService:BindActionAtPriority(
"ChangeKeybind",
ActionHandler,
false,
Enum.ContextActionPriority.High.Value,
Enum.KeyCode.Space
) -- How we can change our keybind
I won’t write out the other method as I had an injury to my fingers so I type too slow. I know the code is probably a bit messy but it works. You can test it out. Simply read through and look at the if statements. In the code you can see checks for: Keys being processed already, keys that already have an action bound
This was using UserInputService however. YOu can use ContextActionService to do this. The logic is similar instead of binding and unbinding actions you bind only when you want to change the keybind. then unbind after. The priorities in this case are noto doing much.
This almost works, but there’s one issue: I would like the key that the player presses to bind something to sink (pretty sure that’s the term) the input to all other bound functions below it.
For example, if the player is hovering over the menu, and then decides to bind a key to click, the game will recognize that the player has clicked the mouse for the keybind change first, then sink the input so the mouse click for the menu won’t ever go through.
Essentially, I want to sink the key that the player inputs with UIS.InputBegan:Wait().
Is this possible?