Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why am I getting a nil value in UserInputService?

Asked by 3 years ago

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"})

2 answers

Log in to vote
0
Answered by
Y_VRN 246 Moderation Voter
3 years ago

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
0
Nope. I should tell you that currentkey is the index the player must press in the keys table which is being tracked by count, not the Enum value itself. I did try if key.KeyCode.Value ~= Enum.KeyCode[currentkey].Value but the problem still resides. veeplerthekrim -5 — 3y
0
I also tried .Name and it didn't print out the error but still ran both conditionals of pressing the correct/incorrect key at the same time. However, I did add a if currentkey == nil and reset the values and found out count is somehow going out the keys index range even though it's being reset. veeplerthekrim -5 — 3y
Ad
Log in to vote
0
Answered by 3 years ago

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.

Answer this question