How to Make a Simple Punch Script

How it works:
When you press the letter P on your keyboard or the mobile button your character will preform the punching animation and deal damage to any humanoid in front of it.

Step 1: Setting up

First create a local script in StarterCharacterScripts. Then, create a Remote Event in ReplicatedStorage called Punch, and lastly, a Script in ServerScriptService.
5

Step 2: Creating The Animation

I am not a very good animator but what I did is go to Build Rig in Plugins selected R15 Block Rig, then went to Animation editor and selected the dummy. Create one key frame where the Dummy is completely still, create a second keyframe where the arm is recoiled back, and a third keyframe where it is landing the punch.

Keyframe Examples

1 2 3

I would recommend going onto YouTube and looking at punching animation tutorials.

Now export the animation to Roblox. Go to the animations page (which you should find when you go to Inventory > Animations) and find the numbers in the URL.

4

You will need these numbers for later.

NOTE: WHEN MAKING A R15 ANIMATION YOU HAVE TO MAKE YOUR GAME R15 ONLY

Step 3: Playing The Animation

Go to the Local Script and type out this:

local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remote = ReplicatedStorage:WaitForChild("Punch")
local ContextActionService = game:GetService("ContextActionService")

The first part gets the players humanoid, which is where the animation will be played. The Remote is the remote event we made earlier in replicated storage. The reason we are using Context Action Service is because as well as binding an action to a key it also can bind actions to a button for mobile users.

local Punch = Instance.new("Animation")
Punch.AnimationId = "rbxassetid://YOUR_ID_HERE"

local IsPunching = false

This is where the animation ID from ealier comes in, just paste the numbers into where it says to. IsPunching is a Debounce that prevents the player from spamming the punches.

local function PunchAction()
    if IsPunching == false then
	    IsPunching = not IsPunching

	    local Punch = Humanoid:LoadAnimation(Punch)
	
	    Punch:Play()
	
	    Remote:FireServer()
	
	    Punch.Stopped:Wait()

	    IsPunching = not IsPunching
    end
end

ContextActionService:BindAction("Punch", PunchAction, true, Enum.KeyCode.P) -- You can change the P to whatever button you want
ContextActionService:SetPosition("Punch", UDim2.new (0.72, -25, 0.20, -25))
ContextActionService:SetTitle("Punch", "Punch")

If you were to play test the game now you should see your character do the animation, but no damage.

Step 4: Dealing Damage

Go to the Server Script that you created in Server Script Storage and type out this:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remote = ReplicatedStorage:WaitForChild("Punch")

Remote.OnServerEvent:Connect(function(Player)
    local Character = Player.Character
    local Humanoid = Character:WaitForChild("Humanoid")

    local Params = RaycastParams.new()
    Params.FilterType = Enum.RaycastFilterType.Blacklist
    Params.FilterDescendantsInstances = {Character}

    local Origin = Character.HumanoidRootPart.Position
    local Direction = Character.HumanoidRootPart.CFrame.LookVector * 5
    local Result = workspace:Raycast(Origin, Direction, Params)

What we are doing is using Raycasting to find a humanoid in front of the player. There are many ways to do this but I think raycasting fits best.

First, we find the players, characters, humanoid. Then, we blacklist the players humanoid so the ray doesn’t harm the players own body. Next, we fire the ray from the players humanoid root part. I made mine 5 studs long but you can change it to whatever you feel is best.

    if Result then
        local Damage = 10  
		local Part = Result.Instance
		local Enemy = Part.Parent:FindFirstChild("Humanoid") or Part.Parent.Parent:FindFirstChild("Humanoid")
		
        if Enemy and Enemy:GetState() ~= Enum.HumanoidStateType.Dead then
			Enemy:TakeDamage(Damage)
		end
	end
end)

This part of the script is what deals the damage. If the ray hits an object, and its a humanoid that’s alive, then, it will deal damage (change to what you want).

The end result:
6

Thank you for reading, if you have any feedback, questions, or issues please comment them. :happy1:

112 Likes

This is a pretty clean way to do it. Love it!

10 Likes

Really nice way of putting it. Amazing for beginners!

7 Likes

Great job! I’m definatly steal–… I-i mean, learning this code, haha! :melting_face:

13 Likes

honestly in this case you dont need to use the logical operator “not” for your debounce variables. just do “true” or “false”

3 Likes

For R6, what modify is neccesary?

the animation track to R6

djkdhfiejdjidjfnfdeeyyeeye

1 Like

exploiters can spam the punch remote

1 Like

he said simple, just add a debounce

2 Likes