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

How do I made a keybinded tool bar type thing that can be changed?

Asked by 1 year ago

I didn't really know what to call this but here is what I mean. I have magic abilities, they are keybinded to F or G as of current. I want to make it so that Fireball = G but if I wanted to then I could change maybe Lightning Strike to G. This wouldn't be done by me either, I want it so that the players can do this themselves. This would save up keybinds and allow players to only have certain Spells equipped at one time, not all of them.

To sum it up, Player has Fireball and Lightning Strike spells (as an example), Player can customise which ability is keybinded to what button, max (let's say) 5 buttons. If they have 6 spells unlocked then only 5 can be on at one time each to the keybind of the player's choosing.

As of current, my spells are done with a local script checking for the keybind to be pressed if that player has the local script in their folder. This act will then use a Remote Event to activate the spell which is a server script.

If there's a YouTube tutorial that covers this then that would work too, thanks in advance!

1 answer

Log in to vote
0
Answered by 1 year ago
Edited 1 year ago

Apologies for the rather lengthy answer but hopefully it helps you understand how it might be implemented better than just some code. You can store the keybinds in a datastore, perhaps like this: {userid: {"F":=Lightning","G"="Fireball",...}}

This would look something like this:

local DataStoreService = game:GetService("DataStoreService")

local KeybindStore = DataStoreService:GetDataStore("KeybindDatastore")

local keybinds = {}

game.Players.PlayerAdded:Connect(function(player)
    local data = nil
    local success, data = pcall(function()
        return KeybindStore:GetAsync(player.UserId)
    end)
    if success then
        keybinds[player.UserId] = data
    end
    if data == nil then
        keybinds[player.UserId] = {"F" = "Lightning", "G" = "Fireball"}
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local success, errorMessage = pcall(function()
        KeybindStore:SetAsync(player.UserId, keybinds[player.UserId])
    end)
    if not success then
        print(errorMessage)
    end
end)

The result of this would be a the keybind settings being stored in the keybinds variable. This could be in a server script that also manages firing the abilities. One way of doing this would be to use a remote event. In my code, this would be a RemoteEvent in ReplicatedStorage called "AbilityRemote." Heres how that might look: Local Script in the player:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local abilityEvent = ReplicatedStorage:WaitForChild("AbilityRemote")
local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(inputObject)
    if inputObject.UserInputType == Enum.UserInputType.Keyboard then -- check if input was from keyboard
        local value = inputObject.KeyCode.Value -- the value of the enum
        if value > 96 and value < 123 then -- letters are between 97 and 122
            key = string.char(value):upper() -- convert the enum to a string to pass to our function
            abilityEvent:FireServer(key)
        end
    end
end)

ServerScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local abilityEvent = ReplicatedStorage:WaitForChild("AbilityRemote")

local DataStoreService = game:GetService("DataStoreService")

local KeybindStore = DataStoreService:GetDataStore("KeybindDatastore")

local keybinds = {}

game.Players.PlayerAdded:Connect(function(player)
    local data = nil
    local success, data = pcall(function()
        return KeybindStore:GetAsync(player.UserId)
    end)
    if success then
        keybinds[player.UserId] = data --Get user data when a player joins and put it in the variable
    end
    if data == nil or data == {} then
        keybinds[player.UserId] = {"F" = "Lightning", "G" = "Fireball"} --If the data doesn't exist, create the default data. If you want to add more keybinds, you can add them to this table.
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local success, errorMessage = pcall(function()
        KeybindStore:SetAsync(player.UserId, keybinds[player.UserId]) --Save the player's keybinds when they leave.
    end)
    if not success then
        print(errorMessage)
    end
end)

local function doAbility(player, ability)
    if ability == "Fireball" then
        print("Fireball fired by",player)
        --write some code to deal with fireballs here
    elseif ability == "Lightning" then
        print("Lightning fired by",player)
        --write some code to deal with lightning here
    end
end

local function keyPressed(player, key)
    if keybinds[player.UserId][key] then
        doAbility(player, keybinds[player.UserId][key])
    end
end

abilityEvent.OnServerEvent:Connect(keyPressed)

Now, you can write code to change what keybinds correspond with which actions. How you implement this will depend on your game, but you can again use server events to change the keybinds, perhaps with a button. In my code, this would be handled by a RemoteEvent in ReplicatedStorage called "KeyRemote."

LocalScript in the player:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local abilityEvent = ReplicatedStorage:WaitForChild("AbilityRemote")
local keyEvent = ReplicatedStorage:WaitForChild("KeyRemote")
local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(inputObject)
    if inputObject.UserInputType == Enum.UserInputType.Keyboard then -- check if input was from keyboard
        local value = inputObject.KeyCode.Value -- the value of the enum
        if value > 96 and value < 123 then -- letters are between 97 and 122
            key = string.char(value):upper() -- convert the enum to a string to pass to our function
            abilityEvent:FireServer(key)
        end
    end
end)

--Put this inside a button function, or another function
--key is the key that is being changed, and action is the new action to assign to it
keyEvent:FireServer(key, action)
--Example would be keyEvent:FireServer("F","Fireball")

ServerScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local abilityEvent = ReplicatedStorage:WaitForChild("AbilityRemote")
local keyEvent = ReplicatedStorage:WaitForChild("KeyRemote")

local DataStoreService = game:GetService("DataStoreService")

local KeybindStore = DataStoreService:GetDataStore("KeybindDatastore")

local keybinds = {}

game.Players.PlayerAdded:Connect(function(player)
    local data = nil
    local success, data = pcall(function()
        return KeybindStore:GetAsync(player.UserId)
    end)
    if success then
        keybinds[player.UserId] = data --Get user data when a player joins and put it in the variable
    end
    if data == nil or data == {} then
        keybinds[player.UserId] = {"F" = "Lightning", "G" = "Fireball"} --If the data doesn't exist, create the default data. If you want to add more keybinds, you can add them to this table.
    end
end)

game.Players.PlayerRemoving:Connect(function(player)
    local success, errorMessage = pcall(function()
        KeybindStore:SetAsync(player.UserId, keybinds[player.UserId]) --Save the player's keybinds when they leave.
    end)
    if not success then
        print(errorMessage)
    end
end)

local function doAbility(player, ability)
    if ability == "Fireball" then
        print("Fireball fired by",player)
        --write some code to deal with fireballs here
    elseif ability == "Lightning" then
        print("Lightning fired by",player)
        --write some code to deal with lightning here
    end
end

local function keyPressed(player, key)
    if keybinds[player.UserId][key] then
        doAbility(player, keybinds[player.UserId][key])
    end
end

local function keyChanged(player, key, action)
    if keybinds[player.UserId][key] then
        keybinds[player.UserId][key] = action --set the key to the action
    end
end

abilityEvent.OnServerEvent:Connect(keyPressed)
keyEvent.OnServerEvent:Connect(keyChanged)
Ad

Answer this question