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

How would I concatenate 'inputObject' to match Enum.KeyCode?

Asked by
Ziffixture 6913 Moderation Voter Community Moderator
5 years ago
Edited 5 years ago

This is very tough to explain, I myself took some time trying to make a title. I'm trying to make a pickUp Script and I'm having trouble with the drop portion. I will admit there are definitely flaws, I just sorta went along with it, so I will post the whole Event. Basically, there are 3 undefined carrierSlots; CFrame positions, on the Character at the moment, and the drop function is to index whichever Item is currently in the Slot# that was received by UserInput. The sequence is supposed to go somewhat like this: Holding E - Slot Index (1-3), Right Click. The first two keys are supposed to be held down, Right Click will "drop" the Indexed Item wherever the cursorPoint is currently located.

I have a table that looks like so

local carrierSlotIndex = {
   ["1"] = "One";
   ["2"] = "Two";
   ["3"] = "Three";
};

these are the carrierSlotIndex keys

This is the concatenation line

userInputService:IsKeyDown(
    Enum.KeyCode[carrierSlotIndex[inputObject]]
)

This is the Script

userInputService.InputBegan:Connect(function(inputObject, gameProcessed)
    local cursorPoint = cursor.Hit.p
    if (userInputService:IsKeyDown(Enum.KeyCode.E) and not gameProcessed) then
        if (userInputService:IsKeyDown(Enum.KeyCode[carrierSlotIndex[tostring(inputObject)]])) then
            if (type(inputObject) == "number") then
                for _,inputObject_ in ipairs(carrierSlotIndex) do
                    if (inputObject_ ~= carrierSlotIndex) then
                        return false
                    end
                    if (cursorPoint ~= cursorPoint) then cursorPoint = cursor.Hit.p end
                    print("Dropped Item")
                    local carrierItems = carrierInventory:GetChildren()
                    local carrierItem = carrierItems[inputObject]
                    if (carrierItem ~= nil) then
                        if (inputObject.UserInputType == Enum.UserInputType.MouseButton2) then
                            local weld = findObject(carrierItem,"Weld", "weld")
                            if (weld) then weld:Destroy() end
                            local setSlickDetector Instance.new("ClickDetector"); setSlickDetector:Clone().Parent = carrierItem
                            carrierItem.CFrame = CFrame.new(0,0,0)
                            carrierItem.Parent = workspace
                            carrierItem.Position = cursorPoint          
                            carrierItem.Anchored = true
                            break
                        end
                    end
                end
            end
        end
    end
end)

This question is quite a lot so I'd really appriciate to whomever can provide a working answer, I'll accept it right off the bat and upvote too! Thanks!

If there is anything confusing about my explanation, please feel free to ask me to elaborate

I've also done some testing and removed tostring() from the concatenation line. I now got bad argument #2 to '?' (string expected, got nil) what am I doing wrong?!

1
I dont know the answer but i applaud how well you've explained the question. DinozCreates 1070 — 5y
0
Thanks Ziffixture 6913 — 5y
1
This will not work. 'inputObject' is just an instance (like parts, scripts, models, etc) with the KeyCode and UserInputType and all those properties. User#24403 69 — 5y
0
InputObject is the key pressed right? Ziffixture 6913 — 5y
View all comments (4 more)
0
A, B, C, you can concatenate this with Enum.KeyCode then by saying Enum.KeyCode[inputObject] Ziffixture 6913 — 5y
0
InputObject when it comes to numbers isn't "One" "Two" is 1, 2, so I'm making this index the item in the table to make it read Enum.KeyCode.One Ziffixture 6913 — 5y
0
like incapaxian said, InputObject is an object which holds properties of the input GoldAngelInDisguise 297 — 5y
0
How can I use it THEN? Ziffixture 6913 — 5y

1 answer

Log in to vote
1
Answered by
ozzyDrive 670 Moderation Voter
5 years ago

This isn't too simple of a problem as it requires some logical thinking. When you face something like this, break it into multiple smaller components -- that's the first step into modular programming. The way you've thrown everything into one "anonymous" function is not a good practice and will really hurt in the long term as it is very messy.

Here's how I'd approach this issue, without any extra modules. An improvement would be to get rid of the global variables and treat the sequence as one object that handles its own logic. Its creator would then make binds for each step in the sequence.

local Players = game:GetService("Players")
local UIS = game:GetService("UserInputService")

local localPlayer = Players.LocalPlayer
local mouse = localPlayer:GetMouse()

--

local SeqState = {
    none = 0,
    first = 1,
    second = 2,
    third = 3,
}

local inputToSeqState = {
    [{Enum.KeyCode.E}] = SeqState.first,
    [{Enum.KeyCode.One, Enum.KeyCode.Two, Enum.KeyCode.Three}] = SeqState.second,
    [{Enum.UserInputType.MouseButton2}] = SeqState.third,
}

--

local carrierSlots = {}
local lastSequenceState = SeqState.none
local lastChosenNumber = nil

--

    --  Carrier placement logic
local function placeCarrier(carrier, pos)
    carrier.CFrame = CFrame.new(pos)
    carrier.Parent = workspace
end

local function getNumberFromKeyCode(k)
    --  There must be a simpler way
    local e = Enum.KeyCode
    return  (k == e.One or k == e.KeypadOne) and 1 or
            (k == e.Two or k == e.KeypadTwo) and 2 or
            (k == e.Three or k == e.KeypadThree) and 3
end

local seqFunctions = {
    [SeqState.second] = function(inputObject)
        --  This shouldn't be done in the real world as it is a bad practice
        lastChosenNumber = getNumberFromKeyCode(inputObject.KeyCode)
    end,

    [SeqState.third] = function(inputObject)
        local n = lastChosenNumber
        placeCarrier(carrierSlots[n], mouse.Hit.p)
    end,
}

--

local function isInArray(array, val)
    for i = 1, #array do
        if array[i] == val then
            return true
        end
    end
    return false
end

local function getSeqState(inputObject)
    for validInput, seqState in next, inputToSeqState do
        if isInArray(validInput, inputObject.KeyCode) or isInArray(validInput, inputObject.UserInputType) then
            return seqState
        end
    end
end

local function stepSequence(seqState, inputObject)
    if seqFunctions[seqState] then
        seqFunctions[seqState](inputObject)
    end
end

local function isNextStep(last, new)
    return new == last + 1
end

local function processInputBegan(inputObject, processed)
    if not processed then
        local seqState = getSeqState(inputObject)
        if seqState and isNextStep(lastSequenceState, seqState) then
            lastSequenceState = seqState
            stepSequence(seqState, inputObject)
        end
    end
end

local function processInputEnded(inputObject, processed)
    if not processed then
        local seqState = getSeqState(inputObject)
        if seqState then
            if seqState <= lastSequenceState then
                lastSequenceState = math.clamp(seqState - 1, SeqState.none, math.huge)
            end
        end
    end
end

--  Event connections

UIS.InputBegan:Connect(processInputBegan)
UIS.InputEnded:Connect(processInputEnded)

--  Demonstration phase

local function createPart(props)
    local p = Instance.new("Part")
    for prop, val in next, props do
        p[prop] = val
    end
    return p
end

table.insert(carrierSlots, createPart{BrickColor = BrickColor.Red(), Anchored = true})
table.insert(carrierSlots, createPart{BrickColor = BrickColor.Green(), Anchored = true})
table.insert(carrierSlots, createPart{BrickColor = BrickColor.Blue(), Anchored = true})

It doesn't require anything extra, you can just drop it into a LocalScript inside StarterPlayerScripts. I'd still suggest to experiment with it and implement it on your own, for the sake of experience.

0
I am so confused Ziffixture 6913 — 5y
0
I'll gladly explain whatever you're confused with. The most confusing part might be SeqState, which is just an enum to describe the current position of the sequence. I was also very confused with what exactly were you asking, and went along with the original goal, which was the key sequence. ozzyDrive 670 — 5y
Ad

Answer this question