Collimator/Reflex sights

I’ve been trying to achieve an effect similar to a head-up display seen on aircraft, or a reflex sight.

The sight would replicate projecting the gui into an abitrary distance away from the part.
Mark_III_free_gun_reflector_sight_mk_9_variant_reflex_sight_animation

My first approach was offsetting the gui proportionally to the camera’s position relative to the part,

20210217_133245 (Rocky_balboa336 assisted in documenting it)

Where the gui is cut of once it exceeds the edge of the part.

I used CFrame:PointToObjectSpace() to derive the relative position of the camera, however, for the CFrame component, I unfortunately used world positions to generate the CFrame. As I wanted to use this in aircraft, any change in orientation would not be translated relative to the part, throwing it off. (This was mostly my bad).

At first glance it seems ok when stationary, but it has a slight delay between when the camera moves and when it responds, making the gui appear to “follow” the camera instead of simulating the projection.

Due to the nature of the collimated projection, that is, the light beams are generally parrellel (like sunlight), it would make the projection appear to be an infinite distance away (due to parallax) and it would be safe to assume that the offset of the GUI should be 1:1 to the offset of the camera. Hence the offset of the GUI can be calculated by the PixelsPerStud of the GUI multiplied by the offset of the camera.

If the camera to gui offset is <1:1 then it would make the gui appear closer than optical infinity.

TLDR
A bit of lag and a lot of CFrame.

Feel free to ask for clarification.

2 Likes

Can you please show us the script?

My apologies for not updating this post earlier;
I’ve continued working on it and have largely managed to get it working to my expectations.

I appreciate your engagement nonetheless.

To close this thread (and for future reference);

I had a local script that would

  1. Get the camera’s position (in studs) to the screen’s object space.

I can use the surface gui’s PixelsPerStud value to then calculate the Udim2 positions for the gui elements,

For example,

-- This would be done on local script

local part = -- the screen part in which the surface gui resides

local camera = workspace.CurrentCamera

local update = function() -- you'd bind this to render stepped or :BindToRenderStep
  -- Assigning the camera's position in object space
  local CameraPosition = part.CFrame:PointToObjectSpace(camera.CFrame.p)

--[[
From here, we can use the X and Y values of CameraPosition to figure out where to place the gui
]]

end
2 Likes

Could we get a file with the place / opensource game?

3 Likes