I'm trying to make a punch script and I'm handling the OnTouched event in Localscript (this whole script is a localscript). Yes, I want to deal damage, but at the same time make the RemoteEvent secure and as server-sided as possible so exploiters cannot manipulate it. I cannot think of a way to do it, however.
local punchConnection punchConnection = LeftHand.Touched:Connect(function(interacted) -- Punch Variables were placed in an event to randomize them more. -- local PunchDamage_Range = math.random(4, 8) -- Randomized Range of Damages for Punch. local PunchCritical = math.random() -- Chance of Critical Hit if Player hits another Player in the Head. local interactedHumanoid = interacted:FindFirstChild('Humanoid') or interacted.Parent:FindFirstChild('Humanoid') if interactedHumanoid ~= nil and interactedHumanoid ~= Humanoid and not Hit and Punching then Hit = true if interacted.Name == 'Head' and PunchCritical >= 0.85 then -- N/A else -- Line where I want to do damage end wait(PunchCooldown) Hit = false punchConnection:Disconnect() end end)
Any ideas? If so, please help, thanks!
First of all, do NOT calculate the damage client sided. This opens up the possibility of sending any number of damage to the server for exploiters (insta kill, .etc).
Second of all, your best possibility is probably to do distance (so they cant do it from anywhere) and time (so exploiters cant rapid fire punch).
so basically first we need to define max distance, wait time and if the target actually has a humanoid!
local maxDistance = 10 --Change this to what you want (I have 10 as a generally good number) local waitTime = 1 --Wait one second before able to hit again local tHum = target:FindFirstChild("Humanoid")
Now theres many ways you can register the players last hit time but I like to use a table in my preference:
local lastHitTime = {} --We're going to create a dictionary for the players so its easily accessible
Now we need to go serverside.
First we need to check the target exists, work out distance then check time
To work out distance
local distance = (player.Position - target.Position).magnitude
Magnitude gives us the distance in studs between the target and the player.
we then check if its too far or not:
if distance <= maxDistance and tHum then
What we have so far:
local maxDistance = 10 --Change this to what you want (I have 10 as a generally good number) local waitTime = 1 --Wait one second before able to hit again local lastHitTime = {} --We're going to create a dictionary for the players so its easily accessible game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, target) local distance = (player.Position - target.Position).magnitude if distance <= maxDistance and tHum then end end)
Now we need to check the last time they hit, for this we'll use roblox's tick() this tells us how many seconds have passed since the UNIX epoch
if lastHitTime[player.Name] then --If they've never hit before they won't have a last hit time if tick()-lastHitTime[player.Name] >= waitTime then tHum:TakeDamage(math.random(4, 8)) --we'll just move the math random here for ease lastHitTime[player.Name] = tick() --we need to update the lastHitTime end else tHum:TakeDamage(math.random(4, 8)) --we'll just move the math random here for ease lastHitTime[player.Name] = tick() --we need to update the lastHitTime end
And now the whole thing:
local maxDistance = 10 --Change this to what you want (I have 10 as a generally good number) local waitTime = 1 --Wait one second before able to hit again local lastHitTime = {} --We're going to create a dictionary for the players so its easily accessible game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, target) local distance = (player.Position - target.Position).magnitude local tHum = target:FindFirstChild("Humanoid") if distance <= maxDistance then if lastHitTime[player.Name] then --If they've never hit before they won't have a last hit time if tick()-lastHitTime[player.Name] >= waitTime then tHum:TakeDamage(math.random(4, 8)) --we'll just move the math random here for ease lastHitTime[player.Name] = tick() --we need to update the lastHitTime end else tHum:TakeDamage(math.random(4, 8)) --we'll just move the math random here for ease lastHitTime[player.Name] = tick() --we need to update the lastHitTime end end end)
Hope this helps! feel free to contact me if you need more help!