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
local value = inputObject.KeyCode.Value
if value > 96 and value < 123 then
key = string.char(value):upper()
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
end
if data == nil or data == {} 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)
local function doAbility(player, ability)
if ability == "Fireball" then
print("Fireball fired by",player)
elseif ability == "Lightning" then
print("Lightning fired by",player)
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
local value = inputObject.KeyCode.Value
if value > 96 and value < 123 then
key = string.char(value):upper()
abilityEvent:FireServer(key)
end
end
end)
keyEvent:FireServer(key, action)
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
end
if data == nil or data == {} 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)
local function doAbility(player, ability)
if ability == "Fireball" then
print("Fireball fired by",player)
elseif ability == "Lightning" then
print("Lightning fired by",player)
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
end
end
abilityEvent.OnServerEvent:Connect(keyPressed)
keyEvent.OnServerEvent:Connect(keyChanged)