Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to determine if a model is within a cylinder?

For my Bleach RPG, I am creating a Cero beam attack that will launch out and damage enemies. It's pretty much a basic cylinder mesh that launches forward (like a Kamehameha from Dragon Ball), and will damage whatever enemy character is within the beam. I managed to get it to work, but I feel that there is a better way to do this.

Here's what I did so far...

function clamp(n, bound)
	if n > bound then
		return bound
	elseif n < -bound then
		return -bound
	end
	return n
end

_G.ClosestPointOnPart = function(point, part)
	local p = part.CFrame:vectorToObjectSpace(point-part.Position)
	local hz = part.Size/2
	local pointOnPart = Vector3.new(clamp(p.x, hz.x), clamp(p.y, hz.y), clamp(p.z, hz.z))
	return part.Position + part.CFrame:vectorToWorldSpace(pointOnPart)
end

--[[
CheckCylinderCollisions returns a table of every enemy within the cylinder.

table targets - Variable contains every enemy model we want to check for collisions
Vector3 base - The start position of the cylinder
int dist - How long the cylinder is (not used)
Vector3 lv - The direction the cylinder is pointing
int max_dist - The radius of the cylinder

]]

_G.CheckCylinderCollisions = function(targets,base,dist,lv,max_dist)
	local new_targets = {}
	for i,v in pairs(targets) do
		local h = v:findFirstChild("Humanoid")
		if h and h.Health > 0 then
			local pos = _G.ClosestPointOnPart(base,v.Torso)
			--local dist2 = (base-pos).magnitude
			--local A = CFrame.new(base,pos).lookVector
			--local B = lv --*dist
			--local d = math.sqrt(dist2^2-A:Dot(B)^2)
			local p1 = (base-pos)
			local p2 = (p1:Dot(lv))*lv
			local d = (p1-p2).magnitude
			
			if d <= max_dist then
				local tab = {Target = v, Position = pos}
				table.insert(new_targets,tab)
			end
		end
	end
	return new_targets
end

1 answer

The more efficient way to do this is to use raycasting, cast a ray from the intial position the the end position. After that use FindPartOnRay() to return the hit parts.

This discussion is preserved as it was. New answers, comments, and votes are closed.