Raycast Hitbox 4.01: For all your melee needs!

I did that a couple months ago (right after posting it here) and it worked, thank you anyways!

1 Like

Every time I try using HitStart() it just spits out a error saying “attempt to call a nil value”. Nobody else seems to be having this issue, so I have no idea what I’m doing wrong.

it keeps hitting my humanoid. is there a way to fix this while having it still damage other players?

1 Like

Did you require() the module?

local RaycastHitbox = require(RaycastHitboxModule)

I literally copied the code from the GitHub tutorial with zero edits and keep getting an “attempt to index nil” error. I have the module in ReplicatedStorage and have a part with attachments just like the tutorial (taking things step by step to make sure it’s all working, which it isn’t) so I have no clue what I’m doing wrong. Might just try to write my own code from scratch at this rate…

1 Like

How would I enable debug mode ONLY on the client?
(I have made the hitboxes on the server)

1 Like

Can you get hitboxes on client side? My hitbox was created on server side, and i was wondering if you can interact with it on client.

Event.OnClientEvent:Connect(function(vizualize: BoolValue, HitboxObject)
	local hitbox = HitboxModule:GetHitbox(HitboxObject)
	if hitbox~=nil then
		hitbox.Visualizer=vizualize
	else
		warn("No hitbox found!")
	end
end)

(It says no hitbox found)

Did you mean so the client will see all the other players hitboxes including his own?
If not:
Make the hitboxes be visualized on client instead of using debug mode

--client side script
hitbox.Visualizer=true

Huh, can you please clarify?

chars

Im confused what are you trying to clarify, you’re asking how you can make the debug mode on client?
You should make a RemoteEvent and put LocalScript inside so only client will see the visualization.

inside the client script make a connection which connects to a OnClientEvent

Event.OnClientEvent:Connect(function(hitbox, IsVisualizing: BoolValue)
       hitbox.Visualizer=IsVisualizing
end)

but it doesnt work itself even for me, i tried to get hitboxes from hitboxObject but it returns nil after all and i cant make it client-sided so i will just wait till someone helps me

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