Hitbox doesn't detect sometimes with :GetPartsInPart()

I have a hitbox system where every time you click a hitbox spawns by a remote event and is welded to your sword then deletes itself after the swing animation but It sometimes doesn’t detect especially when you first join the game.

Vid example:

When you click a local script in the sword plays one of the swing animations and fires a remote event that spawns the hitbox. The “HitBoxPart” variable in the local script is an invisible part always in the sword so that the hitbox that spawns can copy its CFrame and size.

Local Script:

local tool = script.Parent
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:FindFirstChild("Humanoid")
local Animator = hum:FindFirstChild("Animator")

local HitBoxPart = script.Parent:WaitForChild("HitBox")

local Hit1 = Animator:LoadAnimation(script:WaitForChild("Hit1"))
Hit1.Priority = Enum.AnimationPriority.Action3

local Hit2 = Animator:LoadAnimation(script:WaitForChild("Hit2"))
Hit2.Priority = Enum.AnimationPriority.Action3

local Hit3 = Animator:LoadAnimation(script:WaitForChild("Hit3"))
Hit3.Priority = Enum.AnimationPriority.Action3

local Hit4 = Animator:LoadAnimation(script:WaitForChild("Hit4"))
Hit4.Priority = Enum.AnimationPriority.Action3

local Hit5 = Animator:LoadAnimation(script:WaitForChild("Hit5"))
Hit5.Priority = Enum.AnimationPriority.Action3

local Hit6 = Animator:LoadAnimation(script:WaitForChild("Hit6"))
Hit6.Priority = Enum.AnimationPriority.Action3


local CanHit = true

local function WaitHit() -- hit cooldown
	task.wait(.34) 
	CanHit = true
end

local function hit()
	task.wait(0.13) 
	script.Parent.HitBoxHit:FireServer(HitBoxPart) -- fires hitbox remote event
end


local HitCount = 1

tool.Activated:Connect(function()	
	
	if CanHit == true and hum.Health ~= 0 then 
		
		if HitCount == 1 then 
			Hit1:Play()
			HitCount = 2
		elseif HitCount == 2 then 
			Hit2:Play()
			HitCount = 3
		elseif HitCount == 3 then 
			Hit3:Play()
			HitCount = 4
		elseif HitCount == 4 then 
			Hit4:Play()
			HitCount = 5
		elseif HitCount == 5 then 
			Hit5:Play()
			HitCount = 6
		elseif HitCount == 6 then 
			Hit6:Play()
			HitCount = 1
		end
		
			spawn(hit)
		    CanHit = false
	     	spawn(WaitHit)
			
	end
end)


Script that listens for the remote event:

script.Parent.HitBoxHit.OnServerEvent:Connect(function(plr,HitBoxPart)
	
	local char = plr.Character
	local Animator = char:FindFirstChild("Humanoid").Animator
	local CanSearch = true

	local weld = Instance.new("WeldConstraint") 
	local hitbox = Instance.new("Part")
	
	hitbox.Name = "hitboxPartSword"
	weld.Parent = hitbox

	hitbox.Anchored = false
	hitbox.CanCollide = false
	hitbox.Transparency = .3
	hitbox.Color = Color3.fromRGB(255, 0, 4)
	hitbox.Size = HitBoxPart.Size
	hitbox.CFrame = HitBoxPart.CFrame
	hitbox.Massless = true
	hitbox.Parent = char
	weld.Part0 = HitBoxPart
	weld.Part1 = hitbox
	
	game.Debris:AddItem(hitbox, 0.13)
	game.Debris:AddItem(weld, 0.13)
	
	local SearchBool = true
	
	local function WhileTimer()  
		task.wait(.2)
		CanSearch = false 
	end

	local function particles(upperTorso)
		local blood = game.ServerStorage.BloodParticlesHit:Clone()
	
		local weld = Instance.new("Weld")
		weld.Parent = upperTorso
		blood.Parent = upperTorso
			weld.Part0 = upperTorso
			weld.Part1 = blood
			blood.Position = upperTorso.Position
		wait()
		     blood.Attachment.ParticleEmitter:Emit(22)
					
		game.Debris:AddItem(blood,2) 
		game.Debris:AddItem(weld,2)
	end

	local params = OverlapParams.new()
	params.FilterDescendantsInstances = {plr.Character:GetChildren()} 
	params.FilterType = Enum.RaycastFilterType.Exclude 

	while CanSearch == true do 
		local hitparts = workspace:GetPartsInPart(hitbox, params) 
		local hitChars = {} 
		
		for i, hitbox in pairs(hitparts) do 
			
			if hitbox.Parent:FindFirstChild("Humanoid") and not table.find(hitChars, hitbox.Parent) then 	
				table.insert(hitChars, hitbox.Parent) 
				
				if hitbox.Parent ~= char and hitbox.Parent.Humanoid.Health ~= 0 then
					
					local hitSound = game.ServerStorage.KatanaImpactSound:Clone()
					
					local upperTorso = hitbox.Parent.UpperTorso
					
					spawn(function()
						particles(upperTorso)
					end)
					
					hitSound.PlaybackSpeed = math.random(1.4,1.7)
					hitSound.PitchShiftSoundEffect.Octave = math.random(1,1.475)
					hitSound.Parent = hitbox.Parent.HumanoidRootPart
					hitSound:Play()
					game.Debris:AddItem(hitSound,.6)
					
					hitbox.Parent:FindFirstChild("Humanoid"):TakeDamage(10) 

				end
			end
		end
		
		if SearchBool == true then
			SearchBool = false
			spawn(WhileTimer)
		end
		
		print(hitChars) 
		params:AddToFilter(hitChars) 
		task.wait() 
	end 
end)	

Both scripts and the remote event are inside the sword tool.

The tool is given after you click a button when you join.

If there is only one swing animation the issue occurs a little less often.

if the hitbox waits more time to delete it occurs a little less often.

In the local script in the hit function where it wait 0.13 seconds if I make it 0.18 it occurs less often but also makes the hits feel delayed.

The particles are there for visual reference, they don’t have anything to do with the bug.

Depending on the server’s step rate and speed of the sword, the hitbox could be outside the character on one frame, and outside the opposite end the next frame. The best way I could think of tackling this is to interpolate the hit box from the previous hit and check in between.

Fixed it by playing all the swing animations when the character joins to load them all.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.