Simple Punch Script

I made a simple punch script, where the player needs to press ‘F’ to punch. Every punch can only deal damage to one person (20 for each punch).


PunchTest.rbxl (28.4 KB)

Workspace:

grafik
RemoteHandler:

local RStorage = game:GetService("ReplicatedStorage")

local Remotes = RStorage:WaitForChild("Remotes")
local Punch = Remotes:WaitForChild("Punch")
local Connection

local function DealDamage(Part)
	local Character = Part.Parent
	local Humanoid = Character:FindFirstChild("Humanoid")
	if Humanoid then
		Humanoid:TakeDamage(20)
		Connection:Disconnect()
	end
end

local function PlayerPunch(Player)
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local RightHand = Character:WaitForChild("RightHand")
	
	Connection = RightHand.Touched:Connect(DealDamage)
	
	wait(0.5)
	
	Connection:Disconnect()
end

Punch.OnServerEvent:Connect(PlayerPunch)

Local Script:

local Players = game:GetService("Players")
local RStorage = game:GetService("ReplicatedStorage")

local Player = Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Remotes = RStorage:WaitForChild("Remotes")
local Punch = Remotes:WaitForChild("Punch")
local Mouse = Player:GetMouse()
local Animation = script:WaitForChild("Animation")
local CanDamage = true

Mouse.KeyDown:connect(function(Key)
	if Key == "f" then
		if CanDamage then
			CanDamage = false
			
			local Humanoid = Character:WaitForChild("Humanoid")
			local PunchAnimation = Humanoid:LoadAnimation(Animation)
			
			PunchAnimation:Play()
			Punch:FireServer()
			
			wait(1)
			CanDamage = true
		end
	end
end)

I got a few points where I’m not sure whether I can do like I did.

  • Shall I assign Connection and DealDamage() (both in RemoteHandler) inside the PlayerPunch function or leave it as it is?
  • Is it dangerous to make a debounce on the client to not fire a RemoteEvent whenever ‘F’ is pressed? If so, are there other possibilities to not fire a RemoteEvent every time?
  • I had a ‘bug’ where one punch did way more damage than supposed (Can’t replicate it). Do any of my scripts have vulnerabilities?
10 Likes

Well firstly, that Connection can be overriden by other players punching at the same time. Not only that but Touched is quite unreliable, I endorse the use of rays here - you could easily raycast in front of the fist when they punch. This module could help with the raycasting:

Secondly, use UserInputService or ContextActionService (which I prefer) instead of KeyDown - KeyDown is deprecated for use, these Services provide much more customisation as well.

Thirdly, yes of course handling the debounce on the client is heavily exploitable - you should really have a dictionary where you have their key as their UserId with the value being their debounce.

For example:

local Debounces = setmetatable({}, {__index = true}) 
--// Returns true if their UserId hasn't be assigned yet

--// In the part where they punch
if Debounces[Player.UserId] then
    Debounces[Player.UserId] = fa;se
    --// Code
    Debounces[Player.UserId] = true
end
4 Likes

generally, i would say if you have something like a punch, sword hit, or something like that
it’s easier to have it be local (yeah it CAN create reach) and have the damage be done on the server (i.e. you hit someone, the server checks if that reach is about correct, and then it applies damage)

(oh also, what i forgot to add)
you may want to consider the use of hittables if you to hit multiple people at the same time:
https://gyazo.com/a90038e52829d77330e360b0459fc292

5 Likes

The script is very vulnerable to exploiters.

I think it could also think that connection could be a little messed up with the other players all punching at the same time.

2 Likes