How i can handle a hitbox function with :GetPartsInPart()?

Im doing a new combat system with a hitbox function using “:GetPartsInPart()” but [i think the loop] works really bad
The function never ends so the game starts lagging as hell

im trying to achieve something like this:
https://gyazo.com/a69a47abbe89b4b371584c756c830e57
But i just got this: (the hitbox appears but dont work bc of the lag)
image

This is the function(is inside a server script)

function Hitbox(Character,DMG,STUN,Duration,WeldedPart,Distance,Knockback,Knockback2,Transparency)
        local debounce = false
        print("HITBOX START")
        local HITBOX = script.SWORDHITBOX:Clone()
        HITBOX.Anchored = false
        HITBOX.Parent = Character
        HITBOX.CFrame = Distance --EXAMPLE: Character.HumanoidRootPart.CFrame + Character.HumanoidRootPart.CFrame.LookVector*4
        HITBOX.Orientation = Character.HumanoidRootPart.Orientation + Vector3.new(0,-90,0)
        HITBOX.Transparency = Transparency
        local weld =  Instance.new("WeldConstraint")
        weld.Part0 = WeldedPart
        weld.Part1 =  HITBOX
        weld.Parent =  weld.Part0
        
        function Damage(hit) --ingore this, this is only effects + dmg
        end

        local parts = workspace:GetPartsInPart(HITBOX)
        game:GetService("RunService").Stepped:Connect(function(step)
            wait(0.01)
            for _, v in pairs(parts) do
                print("HITBOX ACTIVE")
                Damage(v)
            end
        end)
        
        wait(Duration)
        game.Debris:AddItem(HITBOX,0)
        print("HITBOX END")
        debounce = false
    end

i try changing the detection part to this:

while HITBOX and task.wait(0.01) do
	for _, v in pairs(parts) do
		print("HITBOX ACTIVE")
		Damage(v)
	end
end

but didnt work
Oh and there is no chance i change this to raycast or region3 or touched,
raycast module depends on the animation, touched is bad and idk how region3 works

1 Like

did you ever fix this, I’m just wondering out of curiosity

I just reworked all the system but idk how to do a combat system properly

all of my combat systems have lag

For the hitbox though, you can just make it have a table of the things it hit and if an enemy got caught in it you add it to the table and say that if not table.find(table,enemy). You could also make the RunService disconnect when the hitbox ended.

First of all, what happens here is a problem:

local parts = workspace:GetPartsInPart(HITBOX)
game:GetService("RunService").Stepped:Connect(function(step)
       wait(0.01)
       for _, v in pairs(parts) do
              print("HITBOX ACTIVE")
              Damage(v)
       end
end)

You check just once what’s inside the hitbox, and then starts a loop that keeps rechecking what was already checked. Apparently you don’t have any way to recognize if you’ve already damaged a character before too, which means if this hitbox touches a character, the character will keep getting damaged forever. What you should is:

  1. First move the parts variable that stores the parts that are inside the hitbox to inside the loop, so if the hitbox stops touching someone, it won’t keep hitting them anymore.
  2. You need a way to recognize if you’re hitting the same character again the you can’t just hit a same character more than once. To do this, create a table before starting the loop and store the Humanoid’s parent inside the table. Before damaging a Humanoid, you should check if they’re inside the table, and if not, then damage it.

Also, the reason you’re having lag is because you’re not stopping the loop, so Roblox Studio keeps running the loop forever, causing lag eventually. To fix this, you should use the .Destroyed event to check when the hitbox is destroyed (and apparently your hitbox is not even destroyed, so I recommend using the Debris service ato destroy the hitbox after some seconds or miliseconds), and once the hitbox is destroyed, you have to stop the loop you’ve started. To stop the loop you’ve started, put the loop inside a table:

local loop = game:GetService("RunService").Stepped:Connect(function(step)
[...]

After putting the loop inside a table, inside the function the .Destroyed event will run, you have to type:

loop:Disconnect()

Which will disconnect the loop, therefore preventing your game from lagging.

1 Like

Sorry for the late response, I did that system a while ago and it had a lot of errors… Right now my hitbox module looks like this:

function CombatHandler.Hitbox(Player,Size,Position,Weld,Duration)
	local Character = Player.Character or workspace.PlayerCharacters:FindFirstChild(Player.Name)
	local hitbox = Instance.new("Part", Character)
	hitbox.Name = "Hitbox"
	hitbox.CanCollide = false
	hitbox.CanQuery = false
	hitbox.Massless = true
	hitbox.Transparency = 1
	hitbox.Size = Size
	hitbox.CFrame = Position
	
	if Weld ~= nil then
		local weld =  Instance.new("WeldConstraint")
		weld.Part0 = Weld
		weld.Part1 =  hitbox
		weld.Parent =  weld.Part0
	end
	game.Debris:AddItem(hitbox,Duration)
	return hitbox
end


function CombatHandler.HitDetection(Player,Hitbox)
	local Character = Player.Character or workspace.PlayerCharacters:FindFirstChild(Player.Name)
	local OP = OverlapParams.new()
	OP.FilterType = Enum.RaycastFilterType.Exclude
	OP.FilterDescendantsInstances = {Character}
	local DebounceTable = {}
	local Loop 
	local RemovingLoop
	
	print("Starting HitDetection loop")
	Loop = game:GetService("RunService").Stepped:Connect(function(step)
		for _,HitPart in pairs(workspace:GetPartsInPart(Hitbox,OP)) do
			if DebounceTable[HitPart] then
				return 
			end
			DebounceTable[HitPart] = true
			print(HitPart.Name)

			if HitPart.Name == "CharHitbox" or HitPart.Name == "WeaponClashHitbox" then
				print("Sucesfully Detected Hit on Part: "..HitPart.Name)
				return HitPart 
			end
		end
	end)
	
	RemovingLoop = workspace.DescendantRemoving:Connect(function(part)
		if part == Hitbox then
			print("Hitbox Destroyed Detected on HitDetection fuction")
			Loop:Disconnect()
			DebounceTable = nil
			print("HitDetection loop Disconected and DebounceTable Cleaned")
			RemovingLoop:Disconnect()
		end
	end)
end

I dont have any errors or lag whatsoever but I dont think this is the best way I could be doing this and I dont really know if im doing something wrong so please help me and tell me if you find anything wrong.

I think you’re just using workspace.DescendantRemoving unecessarily. As I’ve said in my previous response, you can use the .Destroying event that every part has to detect when the part is getting destroyed (and also wouldn’t need to save the event connection in a variable to disconnect it).