Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by
oggy521 72
5 years ago

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

Log in to vote
2
Answered by
ABK2017 406 Moderation Voter
5 years ago

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
Ad
Log in to vote
2
Answered by
ozzyDrive 670 Moderation Voter
5 years ago
Edited 5 years ago

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.

Log in to vote
0
Answered by
gullet 471 Moderation Voter
5 years ago

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.

Answer this question