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