How do I detect a clients camera seeing an object?

I am currently messing around with studio and I thought it would be interesting to recreate SCP-173 (from the scp foundation) on roblox. Everything is simple for me to do except detecting when the camera sees the SCP mesh. I have done quite a lot of googling and none of the results are really helpful if at all. So can anyone explain to me how this is achieved?

You could use WorldToViewportPoint for pretty good results. Add a buffer or sample multiple points on the mesh to mitigate some issues.

Edit: here’s a slightly more interesting (marginally slower) way that computes the AABB of a part on screen, and does the intersection with the viewport (untested):

-- returns true if a part's 2D bounding box on screen intersects with the screen
-- rect's
local function OnScreen(camera, part)
    -- 1. get all eight points in 3D space for the part

    local pos, front, right, up = part.Position, part.CFrame.LookVector, part.CFrame.RightVector, part.CFrame.UpVector
    local hx, hy, hz = part.Size.X / 2, part.Size.Y / 2, part.Size.Z / 2

    local points = {
        pos - front * hz - right * hx - up * hy,
        pos - front * hz - right * hx + up * hy,
        pos - front * hz + right * hx - up * hy,
        pos - front * hz + right * hx + up * hy,
        pos + front * hz - right * hx - up * hy,
        pos + front * hz - right * hx + up * hy,
        pos + front * hz + right * hx - up * hy,
        pos + front * hz + right * hx + up * hy,
    }
    
    -- 2. compute AABB of the part's bounds on screen
    
    local minX, maxX, minY, maxY = math.huge, -math.huge, math.huge, -math.huge
    
    for i = 1, 8 do
        local screenPoint = camera:WorldToViewportPoint(points[i])
        local x, y = screenPoint.X, screenPoint.Y
        
        if screenPoint.Z > 0 then
            if x < minX then minX = x end
            if x > maxX then maxX = x end
            if y < minY then minY = y end
            if y > maxY then maxY = y end
        end
    end
    
    -- 3. AABB collision with screen rect
    
    local w, h = camera.ViewportSize.X, camera.ViewportSize.Y
    
    return minX < w and maxX > 0 and minY < h and maxY > 0
end
6 Likes