Cylinder-Based Raycast Hitbox

Hello!

This is a simple module I made for my own purposes. I thought I would open-source it so that others may use it as well.

What it does

This generates a cylinder from raycasts to detect if anything is colliding.
If something is colliding, you will be given a RaycastResult.

Source code

This is a module script.

local RadialRaycastCheck = {}

type array<t> = {[number]:t} -- Array variable type
type dictionary<t> = {[string]:t} -- Dictionary variable type

local RaycastPar = RaycastParams.new()
RaycastPar.FilterType = Enum.RaycastFilterType.Blacklist

local PropertyChecks = { -- If any of these are true during the property check, it is ignored in collision
	CanCollide = false,
	Transparency = 1,
}

local function CreateCylinderArray(Position: CFrame, Height: number) -- math :c
	local PositionsArray: array<CFrame> = {}
	
	local BasePosition = CFrame.new(Position.X, 0, Position.Z)
	
	for PosY = Position.Y-Height/2, Position.Y+Height/2, Height/2 do
		for Rotation = 0, math.pi*2, math.pi/30 do
			local NewCFrame = BasePosition * CFrame.new(0, PosY, 0) * CFrame.fromEulerAnglesXYZ(0, Rotation, 0)
			table.insert(PositionsArray, NewCFrame)
		end
	end
	
	return PositionsArray
end

function RadialRaycastCheck:Check(Position: CFrame, Radius: number, Height: number, Ignore: array<any>)
	local NewCylinder = CreateCylinderArray(Position, Height)
	RaycastPar.FilterDescendantsInstances = Ignore
	
	local CollisionResult = nil -- Will be a RaycastResult 
	
	for _, CheckCFrame: CFrame in pairs(NewCylinder) do
		local RaycastResult = workspace:Raycast(CheckCFrame.Position, CheckCFrame.LookVector * Radius, RaycastPar)
		local RaycastInstance = RaycastResult and RaycastResult.Instance
		
		if RaycastInstance then
			local DidCollide = true
			
			for Property, Value in pairs(PropertyChecks) do
				if RaycastInstance[Property] == Value then
					DidCollide = false
					break
				end
			end
			
			if DidCollide then
				CollisionResult = RaycastResult
				break
			end
		end
	end
	
	return CollisionResult
end

return RadialRaycastCheck

How to use it

It’s simple to use!

  • Get the module via require
  • To raycast radially, do module:Check(Position, Radius, Height, IgnoreList)

And that’s it! It will return either a RaycastResult or nil.

11 Likes

This looks awesome! I was planning on doing something like this, but now I don’t have to. :grinning_face_with_smiling_eyes:

I was planning on using a different formula, however.

2 Likes

this is somewhat i need for projectile-based gun system. so thank you.!
by the way, will you add more hitbox classes such as boxcast, spherecast? and vector direction feature for it?

im sorry if i ask you too many questions

2 Likes

Have you done any benchmarks to see how fast this runs?

1 Like

I don’t know if I will, I only made this since I needed it.

1 Like

The following benchmark is completed with boatbomber’s benchmarking plugin:

About 626 ms frame time. Definitely not too expensive, but don’t use it every frame just in case.

Hey! :wave:

Nice job!

I thought I’d mention that I think this script could be improved by specifying how exactly it works.

What I mean is, at first I had a hard time understanding whether this script would shoot a ray out from the CFrame parameter ‘Position’ and use the CFrames Orientation to know in which direction to shoot, or if it would spawn a ‘cylinder’ of rays at the Position parameter, and have every ray point downward/upward to a certain extent. :thinking:

After inspecting your script I now understand that the best way to illustrate your script is like this:

Does this illustration accurately describe what your Cylinder of Rays might look like? :smile:

Point is it would help clarify how the ‘Cylinder Based Raycast Hitbox’ works.
Nonetheless its a good script :+1:

1 Like

Yes, that is a good demonstration for the raycasting!

2 Likes

how to make it stand for car wheels? or it’s just for that direction?

shape casts have been released, they might work better than this resource.

They do, this resource is 3 years old and is not even up to date.

1 Like