Trying to bind input from multiple keys to the same function

I’m trying to make a function that binds keyboard input from every key (except WASD, I and O since those are used for moving and camera) using a for loop. Every time I run this, only the last key (Z) is bound. The other keys are somehow being unbound? I know it’s possible to bind multiple keys to the same function, so what is causing the other keys to unbind?

Also, there has to be a better way of doing this than listing every single key code in a table right?

Anyone know what I’m missing here? (yes I am working in a local script)

local cas = game:GetService("ContextActionService")

local letters = {
	Enum.KeyCode.B,
	Enum.KeyCode.C,
	Enum.KeyCode.E,
	Enum.KeyCode.F,
	Enum.KeyCode.G,
	Enum.KeyCode.H,
	Enum.KeyCode.J,
	Enum.KeyCode.K,
	Enum.KeyCode.L,
	Enum.KeyCode.M,
	Enum.KeyCode.N,
	Enum.KeyCode.P,
	Enum.KeyCode.Q,
	Enum.KeyCode.R,
	Enum.KeyCode.T,
	Enum.KeyCode.U,
	Enum.KeyCode.V,
	Enum.KeyCode.X,
	Enum.KeyCode.Y,
	Enum.KeyCode.Z,
}

local numbers = {
	Enum.KeyCode.One,
	Enum.KeyCode.Two,
	Enum.KeyCode.Three,
	Enum.KeyCode.Four,
	Enum.KeyCode.Five,
	Enum.KeyCode.Six,
	Enum.KeyCode.Seven,
	Enum.KeyCode.Eight,
	Enum.KeyCode.Nine,
	Enum.KeyCode.Zero,
}

local function OnInput(actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		if actionName == "letter" then
			print ("letter pressed")
		elseif actionName == "number" then
			print ("number pressed")
		end
	end
end
for index, item in pairs(letters) do
	cas:BindAction("letter", OnInput, false, item)
end

for index, item in pairs(numbers) do
	cas:BindAction("number", OnInput, false, item)
end

Instead of ContextActionService, I would use just UserInputService for this one.

local UIS = game:GetService("UserInputService")

UIS.InputBegan:Connect(function(Input, IsTyping)
    if IsTyping then return end
    for i, v in pairs(Letters) do
        if Input.KeyCode == v then
            print("Letter Pressed")
            return
        end
    end
    for i, v in pairs(Numbers) do
        if Input.KeyCode == v then
            print("Number Pressed")
            return
        end
    end
end)
1 Like
contextActionService:BindAction(
  --[[actionName=]]"dashAction",
  --[[functionToBind=]]dashAction,
  --[[createTouchButton=]]true, 
  --[[inputTypes=]]unpack(Enum.KeyCode:GetEnumItems()))

Well I tested this for my script and it binded my dash to all the keys. It should work.

Use Enum.KeyCode:GetEnumItems() and then remove the keys you don’t want to bind from the array that is returned. unpack the array, easy.

It’d be (probably) better to just detect keyboard input using UserInputService and then create a blacklist (W, A, S, D, I, O) using an array.

Just so you know

(except WASD, I and O since those are used for moving and camera)"

I think there are probably a bunch of more keys to consider (such as F keys)

1 Like

@RepValor I’m currently using input service but it fires while the players are chatting.

@hamsterloverboy3 I’m trying to map the number keys and the letter keys to two separate functions. Also yeah, there are a lot of key codes in there I don’t need. However, since I’m passing an array of key codes anyway, perhaps I can run unpack on my own arrays. I’ll try that and post the result here.

Edit

YES unpacking my own arrays worked!
I replaced the two for loops in my code above with these two lines.


cas:BindAction("letter", OnInput, false, unpack(letters))
cas:BindAction("number", OnInput, false, unpack(numbers))

4 Likes

You can just upack the table with table.unpack instead of looping through all of the keycodes:

cas:BindAction("letter", OnInput, false, table.unpack(letters))
cas:BindAction("letter", OnInput, false, table.unpack(numbers))

Unpack is a table modifier that technically “deletes” the table({}) but keeps everything inside. So if a table was {"a", "b", "c"} then table.unpack will make it "a", "b, "c".
On the developer hub, any argument located 3rd or higher will be used as an activator for the function(or more so called a tuple argument):
image


Edit: The OP posted this already(I didn’t see it before I posted), but I hope my explanation helped.

1 Like

Also if you don’t want to manually type out the letter array you can use string.char(x) to build the table

local letters = {}
for i = 65, 90, 1 do
  if not (i == 65 or i == 68 or i == 73 or i == 79 or i == 83 or i == 87) then
    table.insert(letters, Enum.KeyCode[string.char(i)])
  end
end

Sadly you can’t do it for numbers because they use words instead of the character. Your original method would probably be better for performance (I assume negligible differences)

1 Like

Bookmarking this for future reference. Thanks!

The code I provided will ignore typing…

I am sure they are familiar with the gameProcessedEvent parameter.