My hitbox sometimes cannot work

I want to let the character move down using tweenService and if there is a character on the ground, the character will do animation, else it just punches the ground.

The issue is I don’t know why the hitbox sometimes can detect the player, and sometimes cannot.

Cannot detect the hitbox

robloxapp-20240818-1800589.wmv (1.8 MB)

Can detect the hitbox
robloxapp-20240818-1801202.wmv (1.7 MB)

I don’t know if is it because the speed is too fast and cause cannot work or other mechanism cause this problem.

Here is the hitbox script:

function CombatModule.CreateHitbox(size, cframe, ignore, weld, char, second, shape)
	if weld == nil then weld = false end
	if(shape == nil) then shape = Enum.PartType.Block end
	
	local hitbox = Instance.new("Part", workspace.Fx)
	hitbox.Name = "hitbox"
	hitbox.Size = size
	hitbox.CFrame = cframe
	hitbox.CanCollide = false
	hitbox.Transparency = 0.6
	hitbox.Anchored = false
	hitbox.Massless = true
	hitbox.Shape = shape
	
	if(shape == Enum.PartType.Cylinder) then hitbox.CFrame = hitbox.CFrame * CFrame.Angles(0, math.rad(90), math.rad(90)) end

	local damageCharacter = {}

	if(not weld) then
		hitbox.Anchored = true
		
		for _, hit in pairs(workspace:GetPartsInPart(hitbox)) do
			if(hit.Parent:FindFirstChild("Humanoid") and table.find(ignore, hit.Parent) == nil and table.find(damageCharacter, hit.Parent) == nil) then
				table.insert(damageCharacter, hit.Parent)
			end
		end
		hitbox:Destroy()
		return damageCharacter
	elseif(weld) then
		print("In weld else")
		hitbox.Anchored = false
		
		local WeldConstraint = Instance.new("WeldConstraint", hitbox)
		WeldConstraint.Part0 = hitbox
		WeldConstraint.Part1 = char.HumanoidRootPart
		
		local connection
		local returnValue = 0
		
		task.delay(second, function()
			connection:Disconnect()
			if(hitbox) then
				print("Destroy hitbox, return {} now")
				hitbox:Destroy()
			end
			returnValue = {}
		end)
		
		print("Created")
		connection = hitbox.Touched:Connect(function(hit)
			print(hit)
			if(hit.Parent:FindFirstChild("Humanoid")  and table.find(ignore, hit.Parent) == nil) then
				connection:Disconnect()
				hitbox:Destroy()
				
				print("hit character, return character now")
				returnValue = {hit.Parent}
			end
		end)
		repeat task.wait() until returnValue ~= 0
		return returnValue
	end
end

and here is the script on the server to call the hitbox function:

elseif(event == "JumpDownTree") then
		HRP.CFrame = CFrame.new(JumpDownPosition) * CFrame.new(0, 650, 0)
		
		local goal = {}
		goal.CFrame = CFrame.new(JumpDownPosition)
		local MoveDownDuration = 2.5
		local tweenInfo = TweenInfo.new(MoveDownDuration, Enum.EasingStyle.Cubic, Enum.EasingDirection.In, 0, false, 0)
		local tween = TweenService:Create(HRP, tweenInfo, goal)	
		tween:Play()
		
		local damageCharacters
		task.spawn(function()
			damageCharacters = CombatModuleScript.CreateHitbox(Vector3.new(18, 7, 7), HRP.CFrame * CFrame.new(0, -5, 0), {Character}, true, Character, MoveDownDuration, Enum.PartType.Cylinder)
		end)
		
		local CanReturn = false

		local tweenConnection
		tweenConnection = tween.Completed:Connect(function()
			tweenConnection:Disconnect()
			CanReturn = true
		end)
		
		repeat task.wait() until CanReturn and damageCharacters ~= nil
		
		if(CanReturn and #damageCharacters == 1) then
			task.spawn(function() TreeJumpPunchCombo(Character, damageCharacters[1]) end)
			return true
		elseif(CanReturn and (damageCharacters == nil or #damageCharacters == 0)) then
			return false
		end
	end

I have try to use print detect already, and when it cannot detect, it print the following words:

In weld else
Created
Destroy hitbox, return {} now

Thank you

(Sorry for need to download the video, i dont know how to upload video)

1 Like

This may be subjective, but for making hitboxes I generally try to avoid .Touched.

Instead of using .Touched you can experiment with using WorldRoot:GetPartsInBoundingBox(), and cycle, by using a while loop, through all of the hit instances until hit.parent returns a player.

It can appear like this

While true do

if not (hit.Parent:FindFirstChild("Humanoid")) and not (table.find(ignore, hit.Parent) == nil) then
    task.wait()
    continue
end

   hitbox:Destroy()			
   print("hit character, return character now")
   returnValue = {hit.Parent}
   break
end

Ofc, judging by your script, you may need to rearrange some things in order to fit this format, however, I suggest you play around with different types of hitboxes.

1 Like

ok, thank you so much, let me have a try

1 Like

seems fixed, thank you so much!!!
but can you explain why touch sometimes cannot work?

1 Like

This is because touched only fires one a object has moved outside it. meaning if your inside it, it wont fire anything.

You can also use workspace:GetPartsInPart() or BasePart:GetTouchingParts() which use OverlapParams which are like RaycastParams, but for collisions.

2 Likes

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