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

How would you activate Global functions and local functions in a keybind?

Asked by 9 years ago

First off, what I am doing is having a single LOCAL script inside the players player gui named "InteractTrigger" Scan for every single part that has a string value named "Interaction" in it. If they step into range (using magnitude of course..) of a part with that String value in it, the script in the player gui will cause a Gui telling them "[e] To interact"

When they press the e Key, it will either perform a local function or a global function and that's where I am stumped.. You see there will be multiple interact-able parts in the game. So every single one will perform a different function when the user presses e while being in range of said part.

All the InteractTrigger script will be doing is checking if the player is in range of a part that has the String value named "Interaction" in it and checks if the player is in range of it and when they press E it will either perform a global function or a local function

Examples If user is in range of part1 and presses E then a gui will be put in their player gui.

If user is in range of part2 and presses E then a brick will be created in the Workspace.

These examples resemble local functions and global functions Part1 is local Part2 is global

I already created a script to check if the player is in range of a part with String Value "Interaction" in it. I already have made the keybind if they press e.

MY PROBLEM I don't know how trigger the global functions and local functions. Because InteractTrigger script is just a framework for doing as said above. It can't just perform the functions to all the parts. There must be a efficient way than just having it disable a script that is inside each part if the user presses e. Because I've tried that and it does not work...

Any other method I could do this? I'm so stumped right now and I worry if I can continue development.

InteractTrigger script

ocal me = game:GetService("Players").LocalPlayer
local mouse = me:GetMouse()

-- REQUIRES: model and descendants of model can have :GetChildren() called
-- on them.
-- PURPOSE: Given a model, returns a list of all of the descendants of that model.
-- [If result is specified, it will add the descendants of result to model.]
function descendants( model, result )
    result = result or {} -- No need to pass in result
    for _, child in pairs(model:GetChildren()) do
        table.insert(result, child) -- Much cleaner way to add to list
        descendants(child, result)
    end
    return result -- Return the accumulated children
end

-- PURPOSE: Returns whether or not this part is an interaction site.
-- REQUIRES: part must be a ROBLOX object.
function isInteraction( part )
    return part:IsA("BasePart") and part:FindFirstChild("Interaction") and part.Interaction:IsA("StringValue")
end

local interactions = {} -- List of all interaction sites.
local everything = descendants( workspace )

for _, object in pairs( everything ) do
    if isInteraction( object ) then
        table.insert( interactions, object )
    end
end

-- Define the GUI we give to players
local interactionGui = game.ReplicatedStorage.InteractionGui

-- Define near, sets to nil
local near

-- REQUIRES: player is a Player, they have a Character (with torso) and PlayerGui.
-- PURPOSE: Shows or hides (by deleting/inserting) the InteractionGui
-- based on whether or not they are close to any interaction site (in `interactions`)
function update(player)
    -- We defined the table of "interactions" above
    local torso = player.Character.Torso
    for _, interaction in pairs(interactions) do
        if (interaction.position - torso.Position).magnitude <= 3 then
            -- Within three studs of interaction's center
            near = interaction
            local mouse = game.Players.LocalPlayer:GetMouse()
            mouse.KeyDown:connect(function(key)
                if near and key == "e"  then
                    interaction.Operation.Disabled = true
                end
            end)
        end
    end
    local playerGui = player.PlayerGui
    local hasGui = playerGui:FindFirstChild( interactionGui.Name )
    if near then
        -- I am near an interaction
        if not hasGui then
            interactionGui:Clone().Parent = playerGui
        end
    else
        -- I am NOT near ANY site
        if hasGui then
            hasGui:Destroy()
        end
    end

end

-- Update all players
function updateAll()
    for _, player in pairs(game.Players:GetPlayers()) do
        if player.Character and player.Character:FindFirstChild("Torso") and player:FindFirstChild("PlayerGui") then
            update(player)
        end
    end
end

while wait(0.1) do
    updateAll()
end
0
"There must be a efficient way than just having it disable a script that is inside each part if the user presses e. Because I've tried that and it does not work..." Wouldn't you want to *enable* the script? In any case, why did it not work? chess123mate 5873 — 9y

1 answer

Log in to vote
1
Answered by 9 years ago

There are certainly ways of doing what you want.

First, a few comments on your script:

-I can't tell if this is a localscript or a server script. It looks like it's a localscript, but then why are you having it loop over all players? It should just repeatedly call "update" on the local player.

-Line 48: If your game is otherwise compatible with mobile devices, consider using the UserInputService instead of the Mouse. ContextActionService.BindActionToInputTypes might also be useful.

-Line 49: mouse.KeyDown is deprecated; user UserInputService.InputBegan instead

-Line 49: You are creating an event potentially every 0.1 seconds for each user. These event connections will build up over time (a memory leak), with the nasty side effect that every time the user presses 'e', the function you've connected to will be called numerous times (once for every time you connected mouse.KeyDown to that anonymous function, which you do every 0.1 seconds if a player is near an interaction).

-Line 51: Wouldn't you want to un-Disable the script? Disabling a script will prevent it from running.

Ways to do what you want:

-Have a Disabled script that can be run by cloning it and then enabling the clone (also putting the clone's parent in the player's backpack or the workspace or something). Those scripts will need a way to know which player activated them; you could add an ObjectValue referring to the Player as a child to the cloned script, for example. (The scripts should delete themselves after they run.)

-Create a BindableFunction (or RemoteFunction, if appropriate) for each Interaction and have a script connect the function to the BindableFunction object. The functions could take, as an argument, which player activated them.

-Having a function or dictionary that converts from an Interaction object to a function. ex, you could have "interactionObjToFunction", a dictionary whose keys refer to the 'interaction' object and whose values refer to the function to run should the player activate the function. Those functions could take the player who activated the interaction as an argument. (Note that this would require the script to record where all the interactions are and precisely what function to run for each, which is probably not what you want).

Ad

Answer this question