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

How to obtain a list of all items hit by a ray?

Is it possible to use a raycast from one point to another, and then making a table of all objects which the ray has passed through, rather than just returning the first object hit?

3 answers

✓ Accepted answer

I dont know if there’s a more effiecient way, but you can repeatedly GetAllParts and then add them to the ignore list until it returns nothing (nil).

local function GetAllParts(Ray)
    local Parts = {}
    local Last
    
    repeat
        Last = workspace:FindPartOnRayWithIgnoreList(Ray, Parts)
        table.insert(Parts, Last)
    until Last == nil

    return Parts
end

You can take advantage of theworkspace.FindPartOnRayWithIgnoreList function. Every time a new contact is found, add it to the ignore list, find the next contact point and repeat the process until there are no points found.

https://gyazo.com/b62269248ed0c683cc1aa0aab3b8c33b

Here's the sample code I wrote to generate the above result:

local function drawRay(ray)
	local part = Instance.new("Part")
	
	part.Name = "ray"
	part.Anchored = true
	part.BrickColor = BrickColor.new("Bright yellow")
	
	local origin, direction = ray.Origin, ray.Direction
	
	part.Size = Vector3.new(0.2, 0.2, direction.Magnitude)
	part.CFrame = CFrame.new(origin, origin + direction) * CFrame.new(0, 0, -direction.Magnitude/2)
	
	part.Parent = workspace
	return part
end

local function drawContactPoint(v3)
	local part = Instance.new("Part")
	
	part.Name = "contact"
	part.Anchored = true
	part.BrickColor = BrickColor.Red()
	
	part.Size = Vector3.new(0.5, 0.5, 0.5)
	part.CFrame = CFrame.new(v3)
	
	part.Parent = workspace
	return part
end

local function getAllContactPoints(ray)
	local parts = {}
	local points = {}
	
	repeat
		local part, point = workspace:FindPartOnRayWithIgnoreList(ray, parts)
		if part then	--	exclude the ray's end point
			table.insert(parts, part)
			table.insert(points, point)
		end
	until not part
	
	return points, parts
end

--

local laser = workspace.laser

local ray = Ray.new(laser.Position, laser.CFrame.LookVector * 200)
drawRay(ray)

local contactPoints = getAllContactPoints(ray)
for _, point in next, contactPoints do
	drawContactPoint(point)
end

EDIT: Made sure the getAllContactPoints function doesn't return the ray's end point.

There's no native way of getting them all, you'll have to loop FindPartOnRayWithIgnoreList and keep adding each hit part to the ignore list until there are no more hits.

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