Raycast Hitbox 4.01: For all your melee needs!

Just wanted to share a solution to a problem I’ve experienced:
When using “RaycastHitbox.new()” the hitbox doesn’t activate, even after using “HitboxObject:SetPoints()” to manually set the points.

My solution was to change the script “HitboxCaster”, specifically the first line of this function:

function Hitbox:_Init()
	if not self.HitboxObject then table.insert(ActiveHitboxes, self) return end

	local tagConnection: RBXScriptConnection

	local function onTagRemoved(instance: Instance)
		if instance == self.HitboxObject then
			tagConnection:Disconnect()
			self:Destroy()
		end
	end

	self:Recalibrate()
	table.insert(ActiveHitboxes, self)
	CollectionService:AddTag(self.HitboxObject, self.Tag)

	tagConnection = CollectionService:GetInstanceRemovedSignal(self.Tag):Connect(onTagRemoved)
end
1 Like

Anyways, how could you make a debug mode setting like Combat Warriors?

1 Like

Combat Warriors handles their hitboxes on the client. If you’re handling your hitboxes on the server, I don’t think there’s a way to toggle the visualizer for a certain client.

2 Likes

Well, how would I create hitboxes on the client?

1 Like

The same way you do it on the server, in a LocalScript. Then whenever the hitbox hits something, you send a signal to the server via a RemoteEvent.

2 Likes

Unsure if anyone has already posted this or not but I encountered some people asking for it so
I’ve made a function that automatically generates attachments (Or Vector3):

function raycastHitbox:DistributePoints(obj: BasePart | Bone, gridRes: IntValue | Vector3, coverVolume: BoolValue)
	assert(gridRes <= 1, "Number of points on each side should be greater than 1")
	
	local offsetTbl = {}

	gridRes = typeof(gridRes) == "Vector3" and gridRes or Vector3.new(1, 1, 1) * gridRes
	-- how many points should be generated on each axis
	local PointsTbl = {
		X = {},
		Y = {},
		Z = {}
	}
	
	for axis, axisTbl in pairs(PointsTbl) do

		for i = 0, gridRes[axis] - 1 do
			print("loop")
			local point = ((i / (gridRes[axis] - 1)) * obj.Size[axis]) - obj.Size[axis] / 2 
			-- calculate the percentage then minus the middle point to find the offset
			table.insert(axisTbl, point)
		end
	end

	for _, x in pairs(PointsTbl.X) do -- recursion
		for _, y in pairs(PointsTbl.Y) do
			for _, z in pairs(PointsTbl.Z) do

				if not coverVolume then
					-- if set to true the points will fill up the whole part, 
					-- if not then it will only cover the surface (Default: Surface)
					if x == PointsTbl.X[1] or x == PointsTbl.X[#PointsTbl.X] 
					or y == PointsTbl.Y[1] or y == PointsTbl.Y[#PointsTbl.Y]
					or z == PointsTbl.Z[1] or z == PointsTbl.Z[#PointsTbl.Z] then
						-- cover the surface only by limiting the value to the corners

						table.insert(offsetTbl, Vector3.new(x, y, z))

					end
					continue	
				end

				table.insert(offsetTbl, Vector3.new(x, y, z))
			end
		end
	end

	self:SetPoints(obj, offsetTbl)
end

I haven’t benchmarked this yet but I’m sure it is more costly than manually setting up points yourself, although if the gridRes value is smaller than 7 then it shouldn’t be that impactful.

Nevertheless there are definitely rooms for improvement, Eg: removing the recursions and make the algorithm applicable to meshes / parts that aren’t triangle
(It will still work on those objects it just wouldn’t be as accurate since you will be covering up air essentially, unless you want pinpoint accuracy then personally I don’t find this a major problem)

In action: https://gyazo.com/a0af1b9b8b63eecc225080b413d1f698

Edit: I have tested the recursion, I putted in 10 gridRes and it looped around 1500 times (Which might be worrying), so keep that in mind before you fully use this. If anyone else has an alternative that doesn’t involve recursion it would be profusely appreciated if you share it with us!.
Depending on how big your weapons are I think 3 or 5 is a reasonable number

2 Likes

This module works fine for me, but 1 in 5 times or so, hits just dont register, i use enough attachments, the hitboxes are on the server and the animations on the client, this is my code

		local Raycast_Params = RaycastParams.new()
		Raycast_Params.FilterType = Enum.RaycastFilterType.Blacklist
		Raycast_Params.FilterDescendantsInstances = {Character,workspace.Map,workspace.Lobby,workspace.Nodes}
		local Hitbox = RaycastHitbox.new(Handle)
				
		Hitbox.Visualizer = true
		Hitbox.RaycastParams = Raycast_Params
				
		Hitbox.OnHit:Connect(function(BodyPart)
		local Entity = BodyPart.Parent				
		local Humanoid = Entity:FindFirstChildOfClass("Humanoid") 
		if Humanoid then
			CombatModule.DealDamage(Humanoid,Settings["Damage"])
		end		
	end)

	Hitbox:HitStart()
	wait(0.3)
	Hitbox:HitStop()			

is this normal?

1 Like

I think i might have found one of the issues, my game features custom rigs , some rigs have children whitch doi not have the entity model as their direct parent
so i replaced

local Entity = BodyPart.Parent

with

for _,entity in pairs(workspace.Entities:GetChildren()) do
      if BodyPart:IsDescendantOf(entity) then
            -- entity is the model
      end
end

so no matter witch part of the model is hit, it will register

2 Likes

I need advice on my combat system using this module. (would be really appreciated)

I have a sword system and it has a block part for the raycasts to hit.
I’m wondering if I should keep doing my current system which is when Player 1 Swings and hits Player 2’s block, it fires an event to that player to get knocked back etc.

Or, if I could figure out a system that would have defender somehow detect when a blade comes in contact with their block on the client. I tried using linked attatchments but it seemed very unreliable, so I’m wondering If I should try the Linked Attatchments for the Block Hitbox or another method.

1 Like

What I did for blocking in my game was when a hit was registered, the server would check if the hit player was blocking, if they were, check if the player who was hitting was in front of the blocking player. If they are, then they get blocked. If not, the hit would ignore the block since the hitting player was behind the blocking player.

1 Like

How do you check whos behind who?

Put both player’s HumanoidRootPart into this function:

local function isInfront(part1, part2)
	local point1, point2 = (part1.CFrame + part1.CFrame.LookVector),(part1.CFrame + part1.CFrame.LookVector*-1)
	local mag1, mag2 = (point1.Position-part2.Position).Magnitude,(point2.Position-part2.Position).Magnitude
	return (mag1 <= mag2)
end

It will return true if part2 is in front of part1.

4 Likes

how we do a debug mode only show debug line one client?

1 Like

Thanks I love this module

4 Likes

guys how do i blacklist the person’s character im on a server script please help i just dont know how to get the player’s character in a server side script

Where is the script located? charss

1 Like

its located in the tool (server script)

1 Like

You would check who the parent of the tool is if the character is holding it. If it’s in the backpack, you would check the parent of the Backpack and get the character from there.

1 Like


In this video when I throw the ball the raycast ends up going too fast and zooming in front of the ball but I want it to stay with the ball, any help?

1 Like

Is this usable for fists? Do i just make attachments on the arm

2 Likes