Help with logic/math required to constantly keep a Vector3 visible on the screen

Hey developers,

I would like to know the best way to go about constantly keeping a Vector3 on my screen. I’m not too sure how to elegantly achieve this and have tried a myriad of things, one being a solution where I try to respect the ROBLOX camera rules and force the camera to look straight at the point (meaning the player head is literally centered on it).

Basically, I am wondering if it’s possible to find a minimum CFrame.Angles rotation to apply to the camera’s CFrame to keep the point on the screen (accounting for the GUI inset). It would also be nice if it could be offset by a certain X, Y so it wasn’t always sitting on the edge of the viewport.

Sorry if I have been vague, I’m just not too sure how to achieve this at all. I know for a fact that workspace.CurrentCamera:WorldToScreenPoint(Vector3 point) will return an x, y position of where the point is relative to the top left of the screen (accounting for GUI inset) alongside a boolean letting us know whether it’s on or off the screen. It may also be useful to know that when the point is off the screen, the x, y coordinates will be negative with respect to what plane it is out of bounds in.

As always, any help is appreciated!

1 Like

Idk if this will help alot but you can try to check if it exist on the screen everyframe and if it left, just offset the camera so it sees it
If i understood what you wanted wrongly please tell me.

If you want an exact amount of how many degrees of rotation you need, you could do:

local LookCFrame = CFrame.lookAt(Camera.CFrame.Position, point)

local LookPitch, LookYaw, _ = LookCFrame:ToEulerAnglesXYZ() --returns angles in radians
local CameraPitch, CameraYaw, _ = Camera.CFrame:ToEulerAnglesXYZ()

local PitchDifference = math.deg(LookPitch - CameraPitch)

print("Position is "..PitchDifference.." degrees (Y) from camera")

The only issue is the solution above doesn’t consider GUI Inset. Depending on your use case, there could be quite a few methods to do this. If you can, could you elaborate a bit more?