ContextActionService:BindAction() not working for first time in for loops

Title is self-explanatory. Here is a simple code:

local function test(actionName, inputState, inputObject)
	--print(actionName, inputState, inputObject.KeyCode)
	print("TEST")
end

for i = 1, 3 do
	print(i)
	game.ContextActionService:BindAction(tostring(i), test, false, Enum.KeyCode.P)
end

When I run this code, it only prints TEST two times, not three. Because I believe when the line executes ContextActionService:BindAction, it should run the function connected inside it. However, it only prints twice.

Now when I edit the for loop to something like this:

for i = 1, 1 do
	print(i)
	game.ContextActionService:BindAction(tostring(i), test, false, Enum.KeyCode.P)
end

The for loop should print 1 (because of print(i)), but it doesn’t print TEST. This proves that ContextActionService:BindAction() does not fire the function in the first iteration of a for loop. Why? Is this supposed to be intentional?

1 Like

Can you print the ActionName and InputState as well? I believe your TEST is firing from both the Begin and End states of only one function, but I’m not entirely sure. Repeat this and see what it says.

1 Like

Good luck trying to figure out what this output means…

According to this Enum.UserInputState.Cancel appears when an action is created whilst the input is already ongoing.

Try adding

return Enum.ContextActionResult.Pass

To the end of your function.

Doesn’t work. It still shows the same output.

You can see in the output provided that the loop is creating the function on its first iteration, as the Action Name is One. I can’t think of any other reasons why it would produce unexpected results, but is it really necessary to bind the same function thrice anyways?

Here’s the full context.

I was trying to make a fly script, a very simple one. And then I came across a bug, when I am moving and press a key to go into flying mode, my character does not fly in the specified direction until I reclick any one of the WASD movement keys.

So, I made it so that, when you press the key to go into fly mode, I run a for loop which has 4 iterations, each binding the same function to one WASD key. For this same function, I put a print statement to indicate the success of binding the function.

The problem is, if I am binding actions to 4 different keys, the print statement inside the function should run 4 times (4 iterations in this for loop), however, it only printed 3. This made me suspicious about for loops so I made the code provided in the post. That’s why I made this post.

The reason Test prints twice is because it fires when the key is pressed and again when its released so im actuality it only fires for 1 of the bindings.

The reason for this is because they’re all bound to the same key.
I believe if you want them all to work you would have to add this code at the end of your function:

return Enun.ContextActionResult.Pass

this allows other actions with the same binding to fire afterwards.

nvm I didn’t realize someone else already said this

Bumping this topic so more people can notice. I am still puzzled on why this happens.

  • Wait step: Add a small task.wait(0.1) after each BindAction call. This gives Roblox time to process the binding.
  • Bind outside the loop: Bind the actions outside the loop, but use a different variable to track which action is triggered. Inside the test function, check the variable to determine how to handle the action