How to find all parts that have intersected a ray?

I want to cast a ray that finds all parts that obstruct its path. Here is my current code:

		local frac = 360 / numRays
		for angle = frac, 360, frac do
			local ray = getRayAtAngle(rootPart, angle, searchDistance )
			local part = game.Workspace:FindPartOnRayWithIgnoreList( ray, { rootPart } )
			if part ~= nil then
				if part.Parent.Name == "Dummy" then
					game.ReplicatedStorage.Events.DamageReplication:FireServer(game.Players.LocalPlayer,part.Parent.Humanoid ,"Player", 45)
				end
			end
		end


The 15 is the damage indicator for my game, so as shown in the picture it only shows up once because the ray stops upon hitting the first enemy

The purpose of this is because after realizing how unreliable the touch event was, I decided to create a hitbox by casting multiple rays around the player. However, I am creating a shockwave AoE attack and that’s when the problem lies. If there’s an enemy behind another enemy, the damage will only be dealt with by the enemy in front because the ray stops upon hitting its first part. So I was wondering if there was a way for the ray to continue casting and find the obstructing parts, or maybe suggest a different way to deal with reliable hitboxes for AoE attacks.

1 Like

Use magnitude they are really really good and efficient do checks on both client and server so the server take less stress.
You have to have an array of enemies which you could iterate through it and get the magnitude

Use a folder to put all of your enemies into. then get children

Ex.

local mag = (pos - pos1).Magnitude
if mag <= 5 then
--Code
end
1 Like

From what I can remember, there’s isn’t a built in function that does this with a ray, you need to create some custom implementation to do that, you can try this

function findAllPartsOnRay(ray)
	local targets = {}
	repeat
		local target = game.Workspace:FindPartOnRayWithIgnoreList(ray, targets)
		if target then
			table.insert(targets, target)
		end
	until not target
	return targets
end

That I found from this post and it was marked as the solution

It will require you to make a change in your code to accustom for receiving a table, something like this if had to guess, would be this after inserting the function in your script

		local frac = 360 / numRays
		for angle = frac, 360, frac do
			local ray = getRayAtAngle(rootPart, angle, searchDistance )
			local parts = findAllPartsOnRay(ray)
			for i,hitpart in pairs(parts) do
				if hitpart.Parent.Name == "Dummy" then
					game.ReplicatedStorage.Events.DamageReplication:FireServer(game.Players.LocalPlayer,hitpart.Parent.Humanoid ,"Player", 45)
				end
			end
		end
1 Like

instead of doing raycasts, you could check the distance between rootparts like this

local distance = (myHumanoiRootPart.Position - TargetRootPart.Position).Magnitude
if distance <= range then
    --do something
end

then you could make a raycast to see if there are any objects between the 2 players. Also you need to verify the position for every player/dummy so for I,v in ipairs() do might be needed.

another way that you can do it is by using region3, but that comes with it’s own limitation in shape and size

A trick I learned from shader dev is that you can represent a point on a line segment as

p = origin+(direction*t)

To make it work for rays just make sure t is positive. T is basically like how far to travel across. What I am trying to get from this is you could like get the surface normal of a part then get a point on it somehow, maybe some size offset with position crap. If you can get a test point on the thing you can just implicitly set up the algebraic problem like

0=normal:Dot((origin+(direction*t)) - testPoint)

Which means t is

t=normal:Dot(testPoint - origin)/normal:Dot(direction)

Just make sure that normal:Dot(direction) is a positive number else u will get projection errors. From there now u can do a simple aabb check with the verticies on the face. Now we have a way of checking how many parts were intersected (have 1 plane per part or have a checker ig)

This video tells pretty much the same math except he uses triangles instead btw

Thank you this worked perfectly for me. As for the other answers, thank you as well!

Anytime! If you have anymore issues don’t be afraid to make another post!