So I have some animations for my combat system, and I want to make it so players feel powerful and the game uses skill, not plain button spamming. For now, I used a touched event to detect punches, but I am afraid it might not work well. Is there a way that is better than this?
Is there something in particular you are concerned about? Touched event should work fine for a punching mechanic.
I recommend using Touched events as well but make the hitboxes around the fists a decent size so it is not difficult to execute moves.
I would normally implement Sounds ( When the player gets punched, and the sound of the fist travelling through the air, that whoosh sound), Some camera shaking when your character gets punched along with a slight blur would be nice to the Damage effect.
Mostly those are the things that would make a punch feel powerful, especially sound and maybe some light particle effect that gets ejected from the fist upon impact.
and also if you didn’t know utilize the :Disconnect() method on the Touched event so it doesn’t get fired multiple times after hitting the player.
How would I make hitboxes on the fists?
You could use WeldConstraints and Parts and Collision Groups, I think that’s how some people do it.
I would weld Parts to the Players Hands (depending on R15).
If you don’t want to do touched, you can use ray casts for a potentially more accurate result. This will also open up more features you can add to the mechanic.
In my opinion, ray casting is better than using .Touched
but it would only detect if a player punched it straight and he got hit, not from the side.
For R6 hitboxes, I like to create Parts with the size 50% bigger than the arms and legs, so if the character’s arm size is (1, 2, 1), the size of the hitbox would be (1.5, 2.5, 1.5). Then I give the hitbox a TouchEvent that damages the humanoid and deletes the hitbox, people may have a different opinion, but this is what works best for me.
The problem for me is that I am not very good at the welding type of stuff. Would I clone the players hand, make it bigger, and weld it? Could you maybe provide script if you have time.
I used this script to weld one part to another when I was making my 3DMG… here it is
local Weld = {}
Weld.new = function(p0, p1)
local Constraint = Instance.new("WeldConstraint")
Constraint.Part0 = p0
Constraint.Part1 = p1
Constraint.Parent = p1
return Constraint
end
return Weld
pretty simple and self explanatory, you can call the module and instance the welds and position the part when the Character loads,
P1 would be the Hand and P2 would be the Hitbox, this is how I used it
player.CharacterAdded:Connect(function(Char)
local GearClone = Gear:Clone()
local Sword = GearClone.Weapons.Sword
local Sword1 = GearClone.Weapons.Sword1
local Torso = Char:FindFirstChild("Torso")
local LeftArm = Char:FindFirstChild("Left Arm")
local RightArm = Char:FindFirstChild("Right Arm")
GearClone.Parent = Char
local GearConstraint = WeldConstraint.new(Torso, GearClone.PrimaryPart)
GearClone.PrimaryPart.Position = Torso.Position + Vector3.new(0, -0.85, -1.15)
local SwordConstraint = WeldConstraint.new(LeftArm, Sword.PrimaryPart)
local SwordConstraint1 = WeldConstraint.new(RightArm, Sword1.PrimaryPart)
Sword.PrimaryPart.Position = LeftArm.Position + Vector3.new(0, -LeftArm.Size.Y/2, 0)
Sword1.PrimaryPart.Position = RightArm.Position + Vector3.new(0, -RightArm.Size.Y/2, 0)
end)
How would I use this with my punching script. Sorry if I sound unexperienced, just kinda confused
--//Added some minor changes to the welding code for efficiency
--//ModuleScirpt\\--
--//Self explanatory
local Weld = {}
Weld.new = function(p0, p1, Pos)
local Constraint = Instance.new("WeldConstraint")
Constraint.Part0 = p0
Constraint.Part1 = p1
Constraint.Part1.Position = Pos
Constraint.Parent = p1
return Constraint
end
return Weld
--//ServerScript\\--
local Players = game.Players
--//We grab the weld module | src.Resources is just folders that are the ancestors of the WeldModule, basically the path
local WeldModule = require(src.Resources.WeldModule)
--//We listen for the player to join
Players.PlayerAdded:Conect(function(Player)
Player.CharacterAdded:Connect(function(Character)
--//Now we want to define our Variables
local LeftHand = Character:WaitForChild("LeftHand")
local RightHand = Character:WaitForChild("RightHand")
--//The hit detection boxes (It can be made in studio and stored in a folder in replicated storage and cloned)
local HitRight = src.Resources.HitBox:Clone()
local HitLeft = src.Resources.HitBox:Clone()
--//Now we weld them..
local RightWeld = WeldModule.new(RightHand, HitRight, (RightHand.Position + Vector3.new(0, RightHand.Size.Y/2, 0)))
local LeftWeld = WeldModule.new(LeftHand, HitLeft, (RightHand.Position + Vector3.new(0, LeftHand.Size.Y/2, 0)))
--[[//That's pretty much all the parts are now welded to the hand, now for hit detection you simply fire a remote from the client when the animation is played and handle everything else
on the server\\]]--
end)
end)
Thanks a lot! Helped me a lot.
Something you may want to consider is a hurtbox. Instead of relying on parts of a humanoid, rely on a root and a general size that fits R6 and/or R15 (depending on if you allow both or force one type). This way, the only damage interactions happening are between your hit and hurt boxes. The root size is consistent between R6 and R15 rigs.
I am confused. So I use just the humanoid root part for hits?
No. Re-read my post. This is what I am suggesting:
Hurtboxes are very different from HumanoidRootParts.
It was also a response to what Kevitz was suggesting rather than an actual reply to the thread.
Should I use welds with hurtboxes too?
So I did this, but it made the put the part somewhere else, not where the players hand was. I used this script:
–//ServerScript\–
local Players = game.Players
local src = game.ReplicatedStorage.CombatResources
--//We grab the weld module | src.Resources is just folders that are the ancestors of the WeldModule, basically the path
local WeldModule = require(src.WeldModule)
--//We listen for the player to join
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
--//Now we want to define our Variables
local LeftHand = Character:WaitForChild("LeftHand")
local RightHand = Character:WaitForChild("RightHand")
--//The hit detection boxes (It can be made in studio and stored in a folder in replicated storage and cloned)
local HitRight = src.HitBox:Clone()
local HitLeft = src.HitBox:Clone()
--//Now we weld them..
HitRight.Parent = workspace
HitLeft.Parent = workspace
local RightWeld = WeldModule.new(RightHand, HitRight, (RightHand.Position + Vector3.new(0, RightHand.Size.Y/2, 0)))
local LeftWeld = WeldModule.new(LeftHand, HitLeft, (RightHand.Position + Vector3.new(0, LeftHand.Size.Y/2, 0)))
--[[//That's pretty much all the parts are now welded to the hand, now for hit detection you simply fire a remote from the client when the animation is played and handle everything else
on the server\\]]--
end)
end)