I have a keybind (h) to fire an event in my game
It is only supposed to fire once, but if you spam it fast enough you can fire it around 10+ times before it is put onto cooldown
code
local player = game.Players.LocalPlayer
local event = game.ReplicatedStorage.Sacrifice
local UIS = game:GetService("UserInputService")
local cd = false
local mouse = player:GetMouse()
local effect = game.Lighting.SacrificeEffect
mouse.KeyDown:Connect(function(key)
key = key:lower()
if key == 'h' and cd == false and not player.Character:FindFirstChild("Sacrificed") then
cd = true
local fade = player.PlayerGui.SPELLFLASH.Red
local tween = game.TweenService:Create(fade, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {["BackgroundTransparency"] = 0})
local tween2 = game.TweenService:Create(fade, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {["BackgroundTransparency"] = 1})
event:FireServer()
cd = false
player.Character.ChildRemoved:Connect(function()
if not player.Character:FindFirstChild("Sacrificed") then
local fade = player.PlayerGui.SPELLFLASH.Red
local tween = game.TweenService:Create(fade, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {["BackgroundTransparency"] = 0})
local tween2 = game.TweenService:Create(fade, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {["BackgroundTransparency"] = 1})
end
end)
end
end)
server code
local event = game.ReplicatedStorage.Sacrifice
local anim = script.Animation
event.OnServerEvent:Connect(function(player)
local char = player.Character
local hum = player.Character:WaitForChild("Humanoid")
local energy = hum:WaitForChild("sacEnergy")
local maxenergy = hum:WaitForChild("MaxSac")
local loadanim = hum:LoadAnimation(anim)
if not player.Character:FindFirstChild("Sacrificed") then
game.ReplicatedStorage.Events.SpellFOV:FireClient(player)
loadanim:Play()
wait(1)
char.LowerTorso.Dagger.Transparency = 1
char.RightHand.Dagger.Transparency = 0
wait(1)
hum:TakeDamage(10)
local val = Instance.new("BoolValue")
val.Name = "Sacrificed"
val.Parent = char
if energy.Value < maxenergy.Value then
energy.Value += 35
wait(3)
char.LowerTorso.Dagger.Transparency = 0
char.RightHand.Dagger.Transparency = 1
wait(15)
val:Destroy()
loadanim:Stop()
end
end
end)
You are able to spam it due to the fact that in the server sided code, you wait 2 seconds before making the BoolValue, in that 2 seconds, the user is still able to click the button. To prevent this, you could add a debounce on the client side that waits for the BoolValue to be created.
cd = true
local fade = player.PlayerGui.SPELLFLASH.Red
local tween = game.TweenService:Create(fade, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {["BackgroundTransparency"] = 0})
local tween2 = game.TweenService:Create(fade, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {["BackgroundTransparency"] = 1})
event:FireServer()
player.Character:WaitForChild("Sacrificed")
cd = false
local UIS = game:GetService("UserInputService")
UIS.InputBegan:Connect(function(key)
if key.KeyCode == Enum.KeyCode.B then
print("pressed b")
end
end)
this is a local script in startercharacterscripts, and when i press B nothing is printed (nvm there was a typo in my script in studio it prints now)
but my main issue with UserInputService is the holding keybinds
I can script the actual keybinds fine but if I try to do something like make the player take damage while they hold M for example, when they release M they keep taking damage
You can use InputEnded to detect when the user stopped holding it, and use UIS:IsKeyDown to detect when the player is holding it.
UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
while UserInputService:IsKeyDown(Enum.KeyCode.M) do
print("holding M")
task.wait()
end
end)
UIS.InputEnded:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.M then
print("stopped holding M")
end
end)
It works fine for me, are you sure you wrote it correctly?
local UIS = game:GetService("UserInputService")
local player = game:GetService("Players").LocalPlayer
local char = player.Character
UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
while UIS:IsKeyDown(Enum.KeyCode.M) do
char:FindFirstChild("Humanoid"):TakeDamage(10)
task.wait(2)
end
end)
UIS.InputEnded:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.M then
print("stopped holding M")
end
end)
UIS.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input == Enum.KeyCode.M then
game.ReplicatedStorage.DamageStart:FireServer()
end
end)
UIS.InputEnded:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input == Enum.KeyCode.M then
game.ReplicatedStorage.DamageEnd:FireServer()
end
end)
server
game.ReplicatedStorage.DamageStart.OnServerEvent:Connect(function(player)
repeat
wait(2)
player.Character.Humanoid:TakeDamage(10)
until
game.ReplicatedStorage.DamageEnd.OnServerEvent:Connect(function(player)
end)
end
end)
i originally used a different loop to do the damage and it worked until i tried to stop the loop
i think it was a “repeat until” loop i used before
-- client
UIS.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.KeyCode == Enum.KeyCode.M then
game.ReplicatedStorage.DamageStart:FireServer()
end
end)
UIS.InputEnded:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.KeyCode == Enum.KeyCode.M then
game.ReplicatedStorage.DamageEnd:FireServer()
end
end)