Ok, I’ve never been any more frustrated in my life then I am now. Roblox isn’t making any sense for me right now and I need help on whatever is going on.
Basically, I have this simple hit script
Mouse.Button1Down:Connect(function()
if Debounce == false then
Debounce = true
CanHit = true
game.ReplicatedStorage.RemoteEvents.PlayWoosh:FireServer()
StrikeAnimation:Play()
GlobalStrikeAnimation:Play()
delay(.65,function()
Debounce = false
CanHit = false
end)
end
end)
WeaponModel.Stick.Touched:Connect(function(Target)
spawn(function()
if CanHit == true then
local Hit, Kill = game.ReplicatedStorage.RemoteEvents.CheckMeleeHit:InvokeServer(Target,Weapon)
if Hit ~= nil then
print("HIT!")
CanHit = false
Player.PlayerGui.Game.Sounds.Hit:Play()
Mouse.Icon = "http://www.roblox.com/asset/?id=6951512894"
wait(.25)
Mouse.Icon = "http://www.roblox.com/asset/?id=409468479"
end
if Kill == true then
game.ReplicatedStorage.RemoteEvents.Kill:Fire(Hit)
end
end
end)
end)
Simple right? It’s a knife script with a debounce so people can’t spam it, but for SOME REASON, the debounce portion isn’t working. “Hit!” is getting printed twice on some knife strikes, even though I have the debounce incorporated. What should be happening is canhit is true initially, then if Hit ~= nil meaning that the player has hit someone, canhit is false. Making it impossible to be able to hit again until the debounce is finished.
This won’t make it work 100% of the time, since the weapon will most likely be hitting things other than a player. And once it hits something player or not, it locks it completely.
How about if Hit ~= nil and CanHit then (leave your initial CanHit check above that as it is, just check again after the server response)
Cuz right now what’s probably happening is that you check CanHit first, ask server for confirmation which halts the progress before changing CanHit to false, meanwhile hits other thing and since CanHit is still true it asks the server again but it’s already past the CanHit check
WeaponModel.Stick.Touched:Connect(function(Target)
spawn(function()
if CanHit == true then
local Hit, Kill = game.ReplicatedStorage.RemoteEvents.CheckMeleeHit:InvokeServer(Target,Weapon)
CanHit = false
if Hit ~= nil then
Player.PlayerGui.Game.Sounds.Hit:Play()
Mouse.Icon = "http://www.roblox.com/asset/?id=6951512894"
wait(.25)
Mouse.Icon = "http://www.roblox.com/asset/?id=409468479"
else
CanHit = true
end
if Kill == true then
game.ReplicatedStorage.RemoteEvents.Kill:Fire(Hit)
end
end
end)
end)
Then it still didn’t work. Maybe the Invocation of CheckMeleeHit somehow breaks the script?
This inflicts the damage I assume - as I said above, it goes through on client side multiple times through the CanHit check and calls the remote function multiple times - so you should probably have debounce on server
Having debounce server-side for each player is also much better against hackers - the attacks can be spammed on client-side, however, the damage will be correctly inflicted. Imagine shooting a thousand shots but server lets only one of them do damage (client-side debounce is great for animations and visuals that only the player sees tho)
This is because the kill event is in a separate conditional. You would need to test for the same conditions as before (if the player hit a character and if the debounce is true).
I could probably do that but I would have to spawn a function every single time it checks because of the wait in the debounce. And it would have to do it for every player. Wouldn’t that be inefficient?
You could just remember the last time client requested to hit (with something like tick() ) and next time they send a request you just compare new tick() with the previous one and save it to the same variable/table and compare them to see if the debounce time has passed
Yeah That was just my random fixing due to frustration. But I’m talking about the server script. Wouldn’t I have to account for each player on their denounce? It sounds really complicated.
local Script = script
local Tool = Script.Parent
local Handle = Tool.Handle
local function OnTouched()
--Do code here.
end
local function OnActivated()
local Connection
Connection = Handle.Touched:Connect(OnTouched)
task.wait(0.3) --Activation duration.
Connection:Disconnect()
end
Tool.Activated:Connect(OnActivated)
You could just connect the weapon’s Touched signal whenever it is activated and subsequently disconnect it after some time has elapsed.