Binding action to movement keys ends character movement

When the following line runs, the character stops jumping

contextAction:BindActionAtPriority("spaceUp", upAction, 0, false, Enum.KeyCode.Space)

When the key is released the function remains binded and the player can easily jump—But I don’t like the interruption. Same interruption happens with WASD with my movement BindAction. How do I fix that?

switch to UserInputService.InputBegan and UserInputService.InputEnded for better control over jumping and movement. for example

local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == Enum.KeyCode.Space then
        
    end
end)

UserInputService.InputEnded:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == Enum.KeyCode.Space then

    end
end)

I’m aware I could employ this method, but I prefer using the ContextActionService as it has features that gel well with my system

Solutions that still utilize CAS are thus preferred

If no one posts a fix for this, I’m making a bug report. If this behavior is intended let me know!

Were you able to find a solution?

Functions bound to ContextActionService sink input by default. You’ll need to return Enum.ContextActionResult.Pass at the end of the upAction function to allow other actions bound to the same KeyCode or UserInputType to run (It would be best to avoid binding actions to KeyCodes and UserInputTypes which are used by the core scripts, unless you really need to overwrite their behavior, in-order to avoid any possible confusion with your game’s controls compared to other games on Roblox)

@ahmedluai22 The recommendation above should fix the issue for you as well :slight_smile::+1:

1 Like

I do return Enum.ContextActionResult.Pass

In this post I describe the problem persists however

What should I do?

This topic explains what’s causing the issue in your case:

Since you’re binding the action at a lower priority than the one used by the core scripts, it’s being ignored, as the core script’s action is running before your intended one. You’ll need to use a higher priority, such as Enum.ContextActionPriority.High.Value, to fix the problem

Note: Sorry about all the edits on my previous reply, it’s quite late where I live at the moment :sweat_smile:

This should essentially be a tldr, for anyone wondering what the previous post was like

But the problem is actually the opposite: The CoreScript is being overridden by my script. How can I make my function run without interrupting the CoreScript?

I’ve tinkered with different priority values in the past, but I wasn’t able to figure it which one fixes it

1 Like

If the core script’s action is running first, even though you set your action to a higher priority than the one used by the core script (Core scripts use Enum.ContextActionPriority.Default.Value, I believe, which is equivalent to 2000), then I think it’s safe to say that you’re experiencing some kind of bug, since the topic I quoted claims that actions bound to a higher priority should run first

If your action is running before the core script’s, and you’ve set your action to a higher priority, then it should be working as intended (you’ll still need to return Enum.ContextActionResult.Pass at the end of your action’s function, otherwise you’ll block the core script’s action from working)

If your action is running before the core script’s action, and the priority is set to a lower value than the one used by the core script, then there’s either an issue with the documentation (as in, maybe the lower the value, the higher the priority), or you’re experiencing a bug

Ah
One last(I think) question. This is the repro file I made. No worries if not, but if you can, let me know if I did everything alright. Because I’m thinking of updating the thread of my bug report to confirm that this behavior is unintended but I’m still not sure if my code is actually the problem.

1 Like

I managed to find what was causing the problem: It wasn’t happening due to the priority, or due to Enum.ContextActionResult.Pass it was happening because you were binding an action to the W key while the player was already holding it

Essentially, it seems that binding an action to a key that the player is already holding causes whatever action the key was already doing (in this case, the player walking/running) to stop, regardless of the action’s priority or whether or not you’re returning pass


This is an example of what you’ll need to do, using only ContextActionService:

local ContextActionService = game:GetService("ContextActionService")


local thread = nil
local wIsDown = false


local function test()
	while true do -- Will run only if the player presses E while they're holding down W. It won't run if the player presses E before they start walking
		print(true)
		task.wait()
	end
end

local function eAction(_, userInputState: Enum.UserInputState)
	if userInputState == Enum.UserInputState.Begin and thread == nil and wIsDown then
		thread = task.spawn(test)
	else
		if thread then
			task.cancel(thread)
			thread = nil
		end
	end
end

local function wAction(_, userInputService: Enum.UserInputState)
	if userInputService == Enum.UserInputState.Begin then
		wIsDown = true
	else
		wIsDown = false

		if thread then
			task.cancel(thread)
			thread = nil
		end
	end

	return Enum.ContextActionResult.Pass -- Otherwise the player won't be able to walk at all
end

-- You don't need to bind these actions more than once! In fact, doing so will cause problems
ContextActionService:BindAction("EAction", eAction, false, Enum.KeyCode.E) -- Using BindAction instead of BindActionAtPriority is enough in this case
ContextActionService:BindAction("WAction", wAction, false, Enum.KeyCode.W)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.