I'm about to pull my hair out trying to figure this out but I'm making a QTE (Quick Time Event) module that is using UserInputService.
The main function calls up the UI and hooks up a timer, variables, and a few conditional statements to BindToRenderStep and unbinds when the user fails to press the correct button, runs out of time, or completes the QTE. One of those variables is the current key the user must press, however past the first function call, my logic checking if the user is pressing the correct key outputs the current key being nil but somehow fires both conditions.
I printed out the current key and the amount as sanity checks to make sure it was updating on every frame and resetting upon the next call and everything looks to be okay, but my UserInputService logic says otherwise.
Note: UserInputService is hooked up outside BindToRenderStep and animations are synchronized.
Error: (It's line 084 in snippet)
Players.veeplerthekrim.PlayerScripts.QTES:172: invalid argument #2 (string expected, got nil)
Module Code Snippet:
local result function QTES.ShowQTE(period, keys) if playing == true then warn("Cannot interupt current QTE. Wait until this QTE is finished.") return end -- If no args if not period then period = 5 end if not keys or not keys[1] then local r = {"Z", "X", "N", "M"} keys = {} for _ = 1, math.random(2,6) do keys[#keys + 1] = r[math.random(1,4)] end end local oldperiod = period local db = false local count = 1 local currentkey = keys[count] local fail = false -- Start init QTES playing = true -- Create Keys icons for player to press CreateKeys(keys) print(#keys) takeControl() fadeinMenu() local function clearKeys() for _,v in pairs(QTEmenu.QTE_order:GetChildren()) do if v:IsA("ImageLabel") then v:Destroy() end end end -- Frame Check: Unbind if failed, when time runs out, or when currentkey = nil RS:BindToRenderStep("QTETimer", Enum.RenderPriority.Input.Value - 1, function(delta) period -= delta QTEmenu.Timer.bar.Size = UDim2.new(period/oldperiod,0,0.9,0) currentkey = keys[count] print("Current Key = ", currentkey) -- success case if currentkey == nil then RS:UnbindFromRenderStep("QTETimer") Context_act:UnbindAction("freezeAction") QTEmenu.Enabled = false playing = false clearKeys() result = true end -- fail case if period <= 0 or fail == true then QTEmenu.Timer.bar.Size = UDim2.new(0,0,0.9,0) RS:UnbindFromRenderStep("QTETimer") Context_act:UnbindAction("freezeAction") failedAnimation() QTEmenu.Enabled = false playing = false clearKeys() result = false end end) UIS.InputEnded:Connect(function(key) if playing == true and db == false and key.UserInputType == Enum.UserInputType.Keyboard then if key.KeyCode ~= Enum.KeyCode[currentkey] then db = true fail = true failedAnimation() QTEmenu.Enabled = false clearKeys() db = false elseif key.KeyCode == Enum.KeyCode[currentkey] then print(count) db = true gotKeyCorrectEffect(QTEmenu.QTE_order["_"..count]) count += 1 wait(0.1) db=false end end end) end return QTES
Local Script:
local QTES = require(script.Parent) QTES.ShowQTE(4, {"Z","X","Z"}) wait(5) QTES.ShowQTE(4, {"Z","M","N"})
I don't think Enumerations can be accessed by integers. Although Enums have .Name and .Value properties, so you can try this with .Value.
(line 84):
if key.KeyCode.Value ~= currentkey then
(line 91):
elseif key.KeyCode.Value == currentkey then
I got it. Found out that each time I called my function, I was making a new connection with UserInputService, which was tracking old variables in memory. The only thing I had to do was disconnect my function.