How to print something if player presses keys in order on the table

I would make a string and whenever a player presses a button it adds that button to the string, then use string.sub to see if “print” for example is inside of the string.

It needs to be Enum.KeyCode, not just keycode.

Here’s a script I made:

local UserInputService = game:GetService("UserInputService")
local Word = "Hello, world" 
local InputCount = 0
local size = #Word
local debounce = false

UserInputService.InputBegan:Connect(function(InputObject, _)
	if debounce or not (InputObject.UserInputType == Enum.UserInputType.Keyboard) then
		return
	end
	debounce = true
	
	local NextLetter = string.sub(Word,InputCount+1, InputCount+1)
	local IsLetter,PressedLetter = pcall(function() 
-- I used pcall because string.char errors if it's not a normal letter, like pressing shift 
		return string.char(InputObject.KeyCode.Value)
	end)
	
	if NextLetter and PressedLetter == NextLetter:lower() then
		InputCount += 1
		
		if InputCount == #Word then
			print("Correct sequence")
-- If the sequence is correct, this runs
			return
		else
-- this runs every time a letter is correct
			print("Correct letter")
		end
	elseif IsLetter then
		InputCount = 0
		print("Incorrect letter, correct letter was "..NextLetter.." but you pressed "..PressedLetter)
	end
	debounce = false
end)

At the top there’s a variable named “Word”, you can change that out for whatever you need

Method 1:

Animations = {}

function Create_Animations(ids)	
	for i = 1, #ids do	
		Animation = Instance.new("Animation")
		Animation.AnimationId = ids[i]
		Animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(Animation)
		Animation.Looped = false
		Animations[#Animations + 1] = Animation		
	end
end

Create_Animations({'http://www.roblox.com/asset/?id=507770677','http://www.roblox.com/asset/?id=507770818','http://www.roblox.com/asset/?id=507765000'})

game:GetService("UserInputService").InputBegan:Connect(function(keycode)
	if keycode.KeyCode == Enum.KeyCode.Unknown then
		return
	elseif keycode.KeyCode ~= Enum.KeyCode.T and firstbuttonpressed then
		Reset()
	elseif keycode.KeyCode ~= Enum.KeyCode.R and secondbuttonpressed then
		Reset()
	elseif keycode.KeyCode == Enum.KeyCode.T and not firstbuttonpressed then
		Animations[1]:Play()
		firstbuttonpressed = true		
		print("First T pressed")
	elseif keycode.KeyCode == Enum.KeyCode.T and firstbuttonpressed and not secondbuttonpressed then
		Animations[2]:Play()
		Animations[1]:Stop()
		secondbuttonpressed = true
		firstbuttonpressed = false
		print("Second T pressed")
	elseif keycode.KeyCode == Enum.KeyCode.R and secondbuttonpressed then
		Animations[3]:Play()
		Animations[2]:Stop()
		print("Congrats, you've pressed the keys in the correct order. Here's a trophy!")
		firstbuttonpressed = false
		secondbuttonpressed = false
	end
end)

function Reset()
	firstbuttonpressed = false
	secondbuttonpressed = false
	print("Incorrect order")
end

Method 2:

local ContextActionService = game:GetService("ContextActionService")
local firstLetterPressed
local secondLetterPressed
local keyCodesToIgnore = {Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.D,Enum.KeyCode.S,Enum.KeyCode.Up,Enum.KeyCode.Left,Enum.KeyCode.Right,Enum.KeyCode.Backspace,Enum.KeyCode.Space}

local function Reset()
	print("Incorrect Order")
	firstLetterPressed = false
	secondLetterPressed = false
end

local function function1(actionName, inputState, inputObject)
	if actionName == "T" and inputState == Enum.UserInputState.Begin then
		if secondLetterPressed then
			Reset()
		elseif not firstLetterPressed then
			firstLetterPressed = true
		elseif firstLetterPressed then
			secondLetterPressed = true
		end
	elseif actionName == "R" and inputState == Enum.UserInputState.Begin then
		if secondLetterPressed then
			print("YOU WON")
			firstLetterPressed = false
			secondLetterPressed = false
		elseif firstLetterPressed then
			Reset()
		end
	elseif firstLetterPressed and inputState == Enum.UserInputState.Begin then
		Reset()
	end
end

for i,v in pairs(Enum.KeyCode:GetEnumItems()) do
	if not table.find(keyCodesToIgnore, v) then
		ContextActionService:BindAction(string.split(tostring(v), "Enum.KeyCode.")[2], function1, true, v)
	end
end

Both methods work but are poorly optimized.

Here’s my quick thing for it, pretty interesting challenge, nice.

There’s an option for if you want it to be case sensitive.
If the player exceeds the length of the string (“Combination”), it will call OnFailed() and reset the sequence.
However if they succeed, it will call OnSuccess() and reset the sequence.

You can also forcefully reset the sequence by setting _currentInput to an empty string - this also means you can edit the player’s input, for whatever reason you may have.

local UserInputService = game:GetService("UserInputService")

local CASE_SENSITIVE = false

--// What the user will have to type.
local CombinationText = "TTR"

local function OnSuccess()
	print("Player typed it successfully!")
end

local function OnFailed()
	print("Player failed to type it.")
end

local function ConvertToENGChar(Code)
	local ValidCharacter, Character = pcall(string.char, Code.Value)
	
	if ValidCharacter then
		return Character
	end
end

local _currentInput = ""

UserInputService.InputBegan:Connect(function(Object, Processed)
	if Processed then
		return
	end
	
	if Object.UserInputType ~= Enum.UserInputType.Keyboard then
		return
	end

	local actualInput = ConvertToENGChar(Object.KeyCode)
	
	if not actualInput then
		return
	end
	
	local inputtedKey = if CASE_SENSITIVE then actualInput else actualInput:lower()

	_currentInput ..= inputtedKey

	local combinationSuccess = _currentInput == (if CASE_SENSITIVE then CombinationText else CombinationText:lower())

	if combinationSuccess then
		OnSuccess()
		_currentInput = ""
	elseif #_currentInput >= #CombinationText then
		OnFailed()
		_currentInput = ""
	end
end)

After lots of trial and error, I did it: LocalScript.rbxm (1.5 KB)
Code:

local contextActionService = game:GetService("ContextActionService")
local keyCodesToIgnore = {Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.D,Enum.KeyCode.S,Enum.KeyCode.Up,Enum.KeyCode.Left,Enum.KeyCode.Right,Enum.KeyCode.Backspace,Enum.KeyCode.Space}
local pattern = "TTR"
local animations = {"http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677"}
local lastAnimationPlaying = false
local keysPressed = ""

local function animate(i)
	if lastAnimationPlaying then
		lastAnimationPlaying:Stop()
	end
	if i > 1 then
		animations[i - 1]:Stop()
	end
	local animation = Instance.new("Animation")
	animation.AnimationId = animations[i]
	animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(animation)
	animation.Looped = false
	animation:Play()
	animations[i] = animation
end

local function reset()
	animations = {"http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677"}
	keysPressed = ""
	print(keysPressed)
end

local function function1(actionName, inputState, inputObject)
	if inputState == Enum.UserInputState.Begin then
		local i = string.len(keysPressed) + 1
		if actionName == string.sub(pattern, i, i) then
			animate(i)
			keysPressed = keysPressed .. actionName
			if keysPressed == pattern then
				print(keysPressed)
				print("You got the correct order which is " .. keysPressed .. ". Congratulations!")
				lastAnimationPlaying = animations[i]
				task.spawn(function()
					task.wait(lastAnimationPlaying.Length)
					lastAnimationPlaying = false
				end)
				reset()			
			else
				print(keysPressed)
			end
		else
			reset()
		end
	end
end

for i,v in pairs(Enum.KeyCode:GetEnumItems()) do
	if not table.find(keyCodesToIgnore, v) then
		contextActionService:BindAction(string.split(tostring(v), "Enum.KeyCode.")[2], function1, true, v)
	end
end

I recommend using the UIS for stuff where you want to simulate every letter.
You can still use your keyCodesToIgnore array too.

It’s just less signals, so less memory.
This will also make it easier to disconnect / stop listening to keypresses.

Good point. I’m not that familiar with memory usage for Roblox Studio haha. I guess something like this would be better:

local contextActionService = game:GetService("ContextActionService")
local keyCodesToIgnore = {Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.D,Enum.KeyCode.S,Enum.KeyCode.Up,Enum.KeyCode.Left,Enum.KeyCode.Right,Enum.KeyCode.Down,Enum.KeyCode.Space,Enum.KeyCode.Unknown}
local pattern = "TTR"
local animations = {"http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677"}
local lastAnimationPlaying = false
local keysPressed = ""

local function animate(i)
	if lastAnimationPlaying then
		lastAnimationPlaying:Stop()
	end
	if i > 1 then
		animations[i - 1]:Stop()
	end
	local animation = Instance.new("Animation")
	animation.AnimationId = animations[i]
	animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(animation)
	animation.Looped = false
	animation:Play()
	animations[i] = animation
end

local function reset()
	animations = {"http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677"}
	keysPressed = ""
	print(keysPressed)
end

game:GetService("UserInputService").InputBegan:Connect(function(keycode)
	if table.find(keyCodesToIgnore, keycode.KeyCode) then
		return
	end
	local i = string.len(keysPressed) + 1
	local actionName = string.split(tostring(keycode.KeyCode), "Enum.KeyCode.")[2]
	if actionName == string.sub(pattern, i, i) then
		animate(i)
		keysPressed = keysPressed .. actionName
		if keysPressed == pattern then
			print(keysPressed)
			print("You got the correct order which is " .. keysPressed .. ". Congratulations!")
			lastAnimationPlaying = animations[i]
			task.spawn(function()
				task.wait(lastAnimationPlaying.Length)
				lastAnimationPlaying = false
			end)
			reset()			
		else
			print(keysPressed)
		end
	else
		reset()
	end
end)
1 Like

This is perfect, sorry i was away for so long. But can you make it so that if the get any of the sequence wrong, then they have to restart

1 Like

I think my code already does that. That’s what my reset() function does.

So i made it so that you have to press more keys (TTRTTR) and say that i press TTR then the wrong key, then it prints blank but then it has this weird bug. Can tou try it out and change the keys to press to TTRTTR

local contextActionService = game:GetService("ContextActionService")
local keyCodesToIgnore = {Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.D,Enum.KeyCode.S,Enum.KeyCode.Up,Enum.KeyCode.Left,Enum.KeyCode.Right,Enum.KeyCode.Down,Enum.KeyCode.Space,Enum.KeyCode.Unknown}
local pattern = "TTRTTR"
local animations = {"http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677","http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677"}
local lastAnimationPlaying = false
local keysPressed = ""

local function animate(i)
	if lastAnimationPlaying then
		lastAnimationPlaying:Stop()
	end
	if i > 1 then
		animations[i - 1]:Stop()
	end
	local animation = Instance.new("Animation")
	animation.AnimationId = animations[i]
	animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(animation)
	animation.Looped = false
	animation:Play()
	animations[i] = animation
end

local function reset()
	animations = {"http://www.roblox.com/asset/?id=507770818","http://www.roblox.com/asset/?id=507770453","http://www.roblox.com/asset/?id=507770677"}
	keysPressed = ""
	print(keysPressed)
end

game:GetService("UserInputService").InputBegan:Connect(function(keycode)
	if table.find(keyCodesToIgnore, keycode.KeyCode) then
		return
	end
	local i = string.len(keysPressed) + 1
	local actionName = string.split(tostring(keycode.KeyCode), "Enum.KeyCode.")[2]
	if actionName == string.sub(pattern, i, i) then
		animate(i)
		keysPressed = keysPressed .. actionName
		if keysPressed == pattern then
			print(keysPressed)
			print("You got the correct order which is " .. keysPressed .. ". Congratulations!")
			lastAnimationPlaying = animations[i]
			task.spawn(function()
				task.wait(lastAnimationPlaying.Length)
				lastAnimationPlaying = false
			end)
			reset()			
		else
			print(keysPressed)
		end
	else
		reset()
	end
end)

All you have to do is add the same amount of animations as number of letters in the table.

local plr = game.Players.LocalPlayer
repeat wait() until plr.Character
local c = plr.Character
local hrp, hum = c:WaitForChild("HumanoidRootPart"), c:WaitForChild("Humanoid")
local c = plr.Character
local contextActionService = game:GetService("ContextActionService")
local keyCodesToIgnore = {Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.D,Enum.KeyCode.S,Enum.KeyCode.Up,Enum.KeyCode.Left,Enum.KeyCode.Right,Enum.KeyCode.Down,Enum.KeyCode.Space,Enum.KeyCode.Unknown}
local pattern = "TTR"
local animations = {"http://www.roblox.com/asset/?id=9733681660","http://www.roblox.com/asset/?id=9733714087","http://www.roblox.com/asset/?id=9733759672"}
local lastAnimationPlaying = false
local keysPressed = ""
local UserInputService = game:GetService("UserInputService")
local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://9733504813"
local playAnim = hum:LoadAnimation(anim)


local function animate(i)
	if lastAnimationPlaying then
		lastAnimationPlaying:Stop()
	end
	if i > 1 then
		animations[i - 1]:Stop()
	end
	local animation = Instance.new("Animation")
	animation.AnimationId = animations[i]
	animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(animation)
	animation.Looped = false
	animation:Play()
	animations[i] = animation
end

local function reset()
	animations = {"http://www.roblox.com/asset/?id=9733681660","http://www.roblox.com/asset/?id=9733714087","http://www.roblox.com/asset/?id=9733759672"}
	keysPressed = ""
	print(keysPressed)
end

UserInputService.InputBegan:Connect(function(input,i)
	if input.KeyCode == Enum.KeyCode.C then --/let them be able to do the combination
		if script.CanDoAttack.Value == false then
			script.CanDoAttack.Value = true
			print("Enabled")
			playAnim:Play()
			game:GetService("UserInputService").InputBegan:Connect(function(keycode)
				if script.CanDoAttack.Value == true then
					if table.find(keyCodesToIgnore, keycode.KeyCode) then
						return
					end
					local i = string.len(keysPressed) + 1
					local actionName = string.split(tostring(keycode.KeyCode), "Enum.KeyCode.")[2]
					if actionName == string.sub(pattern, i, i) then
						animate(i)
						keysPressed = keysPressed .. actionName
						if keysPressed == pattern then
							print(keysPressed)
							print("You got the correct order which is " .. keysPressed .. ". Congratulations!")
							lastAnimationPlaying = animations[i]
							task.spawn(function()
								task.wait(lastAnimationPlaying.Length)
								lastAnimationPlaying = false
							end)
							reset()			
						else
							
							print(keysPressed)
						end
					else
						reset()
					end
				end

			end)
		else --/supposed to make them not able to do the combinatio, but i dont know how to make it so that if they disable it they have to restart
			
			reset()
			playAnim:Stop()
			print("Disabled")
			script.CanDoAttack.Value = false
		end
		
	end
end)

So i want it so that when they disable it or when “CanDoAttack” is equal to false, when they enable it again they have to restart. I tried it myself and it didnt really work becuase its your script, but can you help me with this?

script.CanDoAttack.Changed:Connect(function(bool))
if bool then
reset()
end
end)

So in a since, theres a lot wrong with this script, if i get the combination right the first time then all animations will stop. But if I get it wrong and then get it right, the animations will still play

idk, but i think that the reset function is missing stuff, because it doesnt reset right