Previous devforum posts havent been much help, and Im concerned that what I want to do might be restricted by robloxs capabilities, which would be frustrating. But Ill still ask.
I’m trying to create an onscreen effect using a beam, and with that comes some immediate restrictions that I’m trying to work around. and viewports are not an option. Ive tried using
which somewhat works and allows me to manipulate it. However, moving it left to right according to my viewportsize in order to find the screen’s edge, but doesn’t seem possible to my knowledge. Please let me know if you know a way.
local camera = workspace.Camera
local screenRatio = camera.ViewportSize.X / camera.ViewportSize.Y
local verticalFOV = camera.FieldOfView
local horizontalFOV = screenRatio * verticalFOV
-- Gets the horizontal offset of a plane facing the camera at a distance of `distance`
local function getHorizontalOffsetAtDistance(distance)
-- This is the distance from the camera ray (center of the screen) to the horizontal edge of the viewing plane
return math.tan(math.rad(horizontalFOV) / 2) * distance
end
This is more of a math problem, so it’s definitely possible on the platform.
Whoops, I didn’t fully think through calculating the horizontal FoV based on the aspect ratio.
The actual equation should be:
local horizontalFOVRad = math.deg(math.atan(math.tan(math.rad(verticalFOV) * 0.5) * screenRatio) * 2)
I tested it using the code below and it the part always stayed at the same spot on the right edge in the middle now.
-- A client code with a small sphere named "Part" in workspace
local camera = workspace.CurrentCamera
local function getHorizontalOffsetAtDistance(distance)
local screenRatio = camera.ViewportSize.X / camera.ViewportSize.Y
local verticalFOV = camera.FieldOfView
local horizontalFOV = math.deg(math.atan(math.tan(math.rad(verticalFOV) * 0.5) * screenRatio) * 2)
return math.tan(math.rad(horizontalFOV) / 2) * distance
end
local part = workspace:WaitForChild("Part")
game:GetService("RunService").RenderStepped:connect(function()
local distance = 1
local cameraOffsetRelative = Vector3.new(getHorizontalOffsetAtDistance(distance), 0, -1*distance)
local cframe = CFrame.new(workspace.CurrentCamera:GetRenderCFrame():PointToWorldSpace(cameraOffsetRelative))
part.CFrame = cframe
end)