Track when a number has been pressed

I’m tryna track when a player presses a number on their keyboard, so I can move their selected inventory slot. However, I want to make this as efficient as possible

local UserInputService = game:GetService('UserInputService')

local Frame = script.Parent

local CurrentSelected = Frame['1']

local function changeSelected(selected)
	CurrentSelected.Backing.ImageColor3 = Color3.fromRGB(200, 200, 200)
	
	CurrentSelected = selected

	CurrentSelected.Backing.ImageColor3 = Color3.fromRGB(0, 170, 255)
end

for _, v in pairs(Frame:GetChildren()) do
	if v:IsA('ImageButton') then
		v.Activated:Connect(function()
			changeSelected(v)
		end)
	end
end

UserInputService.InputBegan:Connect(function(input, GPE)
	if GPE then return end
	
	if input.UserInputType == Enum.UserInputType.Keyboard then

	end
end)

When I print(input.KeyCode) it returns an Enum, as well as the number being ‘One’, ‘Two’ etc. However, my inventories buttons are labelled ‘1’, ‘2’, etc. I got it working with clicking on the individual buttons, I want numbers to work as well

You could convert either the label names to words or key codes to numbers using a lookup table and then compare them and call CangeSelected if there is a match.

E.g.

local dictionary = {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, [0] = Enum.KeyCode.Zero}

Label.Name = dictionary[i]

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	
	if input.UserInputType == Enum.UserInputType.Keyboard then
        if Frame:FindFirstChild(input.KeyCode) then
            changeSelected(Frame[input.KeyCode])
        end
	end
end)

1 Like

This can’t be done

Frame[input.KeyCode]

As KeyCode is an Enum, and as I said in the question, I don’t want to rename the buttons at all. They have to stay as 1, 2, 3

The solution then is to do the opposite, convert the KeyCodes to numbers.

For example:

local dictionary = {Zero = 0, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9}

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	
	if input.UserInputType == Enum.UserInputType.Keyboard then
        if Frame:FindFirstChild(dictionary[input.KeyCode]) then
            changeSelected(Frame[dictionary[input.KeyCode]])
        end
    end
end

local dictionary = {Zero = 0, One = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9}

In order for the direct reference of the input.KeyCode to be indexed in this table, the indexes would need to be a reference to the KeyCode Enum, like so:

local dictionary = {[Enum.KeyCode.Zero] = 0, [Enum.KeyCode.One] = 1, [Enum.KeyCode.Two] = 2, [Enum.KeyCode.Three] = 3, [Enum.KeyCode.Four] = 4, [Enum.KeyCode.Five] = 5, [Enum.KeyCode.Six] = 6, [Enum.KeyCode.Seven] = 7, [Enum.KeyCode.Eight] = 8, [Enum.KeyCode.Nine] = 9}

UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
	
    if input.UserInputType == Enum.UserInputType.Keyboard then
        if Frame:FindFirstChild(dictionary[input.KeyCode]) then
            changeSelected(Frame:FindFirstChild(dictionary[input.KeyCode]))
        end
    end
end

Or you could have the indexes in this table represent the value of the EnumItem and then index this using the KeyCode EnumItem’s value, like so:

local dictionary = {[48] = 0, [49] = 1, [50] = 2, [51] = 3, [52] = 4, [53] = 5, [54] = 6, [55] = 7, [56] = 8, [57] = 9}

UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
	
    if input.UserInputType == Enum.UserInputType.Keyboard then
        if Frame:FindFirstChild(dictionary[input.KeyCode.Value]) then
            changeSelected(Frame:FindFirstChild(dictionary[input.KeyCode.Value]))
        end
    end
end
6 Likes

You can do it by simply subtracting 48 from the keycodes value.

UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
	
    if input.UserInputType == Enum.UserInputType.Keyboard then
        if input.KeyCode.Value == math.clamp(input.KeyCode.Value,48,57) then
            changeSelected(Frame[tostring(input.KeyCode.Value-48)])
        end
    end
end
1 Like

This is another useful method they could use, however the maximum value in the math.clamp function here should be 57, as 58 is the Colon KeyCode

1 Like

Oh right. Forgot about that. Was tired and typing it out on mobile.

local dictionary = {[Enum.KeyCode.One] = 1, [Enum.KeyCode.Two] = 2, [Enum.KeyCode.Three] = 3, [Enum.KeyCode.Four] = 4, [Enum.KeyCode.Five] = 5, [Enum.KeyCode.Six] = 6, [Enum.KeyCode.Seven] = 7, [Enum.KeyCode.Eight] = 8, [Enum.KeyCode.Nine] = 9}

UserInputService.InputBegan:Connect(function(input, GPE)
	if GPE then return end
	
	if input.UserInputType == Enum.UserInputType.Keyboard then
        if Frame:FindFirstChild(dictionary[input.KeyCode]) then -- THIS IS LINE 33
            changeSelected(Frame:FindFirstChild(dictionary[input.KeyCode]))
        end
	end
end)

Does not work
Argument 1 missing or nil

10:56:15.393 - Stack Begin

10:56:15.393 - Script ‘Players.NinjoOnline.PlayerGui.New.Inventory.Bottom.BottomControl’, Line 33

You need to check to see if dictionary[input.KeyCode] exists before using it in FindFirstChild. It will error if you pass nil.

I put a print(input.KeyCode) and it was printing the enum, but still errors (so it’s not nil)

You need to print(dictionary[input.KeyCode]). That is what’s returning nil.

1 Like