I want to achieve making a reliable punching system. I have done so by making it with raycasts, which I heard was the best way to make a punch system.
The system I have made is working, but it isn’t working effeciently. Most of the time, it manages to miss an NPC even though you clearly punch the NPC. Hitting moving NPC’s is thw worst, as the shot always misses. I think this is because I am casting only one ray frome the HumanoidRootPart of the player character.
I have thought about casting multiple rays from different body parts, but that would influence its behaviour while animating. I am also puzzled about how I would cast different rays from the HumanoidRootPart. I tried using hitboxes, but realized quickly that it was ineffective.
I have added comments in my code to make it easier to read.
My code :
-local RS = game:GetService("ReplicatedStorage")
local SS = game:GetService("ServerStorage")
local Remotes = RS.Remotes
-- All remote events
local PunchEvent = Remotes:WaitForChild("PunchEvent")
-- All animations
local PunchAnim = SS.Animations:WaitForChild("PunchAnimation")
PunchEvent.OnServerEvent:Connect(function(player)
--Punch requirements
if not player then return end
if not player.Character then return end
if not player.Character:FindFirstChild("Humanoid") then return end
if player.Character:FindFirstChild("Humanoid").Health <= 0 then return end
local HRP = player.Character:FindFirstChild("HumanoidRootPart")
local Humanoid = player.Character:FindFirstChild("Humanoid")
--Playing Animation
local PunchAnimTrack = Humanoid.Animator:LoadAnimation(PunchAnim)
PunchAnimTrack:Play()
--Creating raycast to detect player
local PunchRaycastParams = RaycastParams.new()
PunchRaycastParams.FilterDescendantsInstances = {player.Character}
PunchRaycastParams.FilterType = Enum.RaycastFilterType.Exclude
PunchRaycastParams.IgnoreWater = true
local Result = workspace:Raycast(HRP.Position, HRP.CFrame.LookVector * 5, PunchRaycastParams)
--Checking raycast result
if not Result then return end
local ResInst = Result.Instance
if not ResInst then return end
if not ResInst.Parent then return end
if ResInst.Parent:FindFirstChild("Humanoid") or ResInst.Parent.Parent:FindFirstChild("Humanoid") then
-- Deal damage to the humanoid
local Target = ResInst.Parent:FindFirstChild("Humanoid")
if Target then
Target:TakeDamage(20)
else
Target = ResInst.Parent.Parent:FindFirstChild("Humanoid")
if Target then
Target:TakeDamage(20)
end
end
end
end)
I hope you can help me to make this system. Thanks a lot for reading this!