Hiding a GUI according an unrelated part's boundary

Hello,

What I am trying to achieve is a paralax free sight on a helicopter but there is an issue.
In order to get a paralax free effect, you need to place the sight further away from you eye, which is what I did, and as I turn my head, the sight picture oversplashes outside the “glass” thats supposed to contain it, which is infront of the pilots eye, due to the great distance between them.

Here’s the example below :
https://gyazo.com/391cd9a2195bc706d4c54b7d0c72ae38

I have read the only post that talks about the same issue I am experiencing :

Here is how the sight object is set in studio :

Yet I cannot seem to find the answer to my case.
Any help would be greatly appreciated.
Have a good day !

UI elements cannot be clipped when they are rotated just to keep that in mind.

…clipping doesn’t work when you are not moving the GUI object. The UI doesn’t follow the player camera.
In a scenario where clipping would work is when you move the reticle frame out of the bounds of a non-moving part.

Have you thought of using a ViewportFrame with a brick modeled reticle, and moving the frames’ Camera according to the players’ head movements? As a ViewportFrames’ camera moves away from the object the object will be clipped when outside of the bounds of the GUI element.

Hi there! I finally got the motivation to figure out a solution.

I did a little research and found that holographic sights have a focal point, basically where the reticle will appear to the user.

To do this in Roblox you basically have to find the intersection of a vector from your camera to the glass of your holographic sight.

You could either do this with raycasting, but I found a better solution using trigonometry.

By drawing the normal vector of the glass, we can get 2 similar triangles

Note that we can get x by projecting the vector from the middle of the glass to the camera onto the normal vector, in Roblox this will look like

local Projection = Normal * (GlassToCam.Magnitude * (GlassToCam.Unit:Dot(Normal)))
local ProjToCamera = GlassToCam-Projection

Let the focal distance be f
the projection magnitude to be m,
the distance from the projection vector to the camera to be c
and the distance from the intersection to the center of the glass to be y

Similar triangles show that
image

The offset of the intersection will be image

This is my code in roblox

local FocalDisance = 10

local Camera = workspace.Camera

local function GetSightOffset(Glass) --Get the intersection of a line from the focal point to the camera on the scope glass
	
	local GlassToCam = (Camera.CFrame.Position - Glass.CFrame.Position)
	local Normal = Glass.CFrame.LookVector
	
	
	
	local Projection = Normal * (GlassToCam.Magnitude * (GlassToCam.Unit:Dot(Normal))) --Projection of glass to camera to glass normal
	local ProjToCamera = GlassToCam-Projection
	
	local OffsetMag = (ProjToCamera.Magnitude * FocalDisance)/(FocalDisance + Projection.Magnitude) --Get distance to line intersection by similair triangles
	local Offset = ProjToCamera.Unit * OffsetMag
	
	return Offset
end

local function UpdateSightPosition(Sight,Offset) --My solution to converting the offset into a Udim2 because I have little clue how they work
	local StudX = Sight.Size.x
	local StudY = Sight.Size.y
	
	local Retical = Sight.SurfaceGui.Frame.Retical
	
	Retical.Position = UDim2.new(-Offset.X/StudX,0,-Offset.Y/StudY,0)
	
	
end

local TestSight = workspace.Sight
 
local FocalInt = Instance.new("Part")
FocalInt.Anchored = true FocalInt.CFrame = TestSight.CFrame * CFrame.new(0,0,FocalDisance) FocalInt.Size = Vector3.new(1,1,1) FocalInt.Parent = workspace

while true do UpdateSightPosition(TestSight,GetSightOffset(TestSight)) game:GetService("RunService").RenderStepped:Wait() end

The code looks something like this

I haven’t tested this on a smaller reticle, but I’m happy with the results. If I decide to make any improvements when I finish my FPS framework I will be sure to update this post

If you have any suggestions or questions, please comment. (though I don’t check the forum very consistently)

6 Likes

Hi there,

What are the chances of getting a reply from you, the person in the post I quoted that was looking for the same thing as I did. What you did there is amazing but I am having issues with it as I am not getting the expected results as seen in the gif :
https://gyazo.com/7190105b0ec9fa1e496f36312c57a548

I went ahead and deleted the lines that create the “FocalInt” part as it serves no functions and it was annoying me more than anything. The rest of your script remains untouched.

You can also see what my workspace looks like, did I mess up anything here hence why the faulty results ?
Any further help from you would be greatly appreciated.

I have found the issue and I had to modify some values and I came up with this script:

local FocalDisance = 10

local Camera = workspace.Camera

local function GetSightOffset(Glass) --Get the intersection of a line from the focal point to the camera on the scope glass
	

	local GlassToCam = (Camera.CFrame.Position - Glass.CFrame.Position)
	local Normal = Glass.CFrame.LookVector


	local Projection = Normal * (GlassToCam.Magnitude * (GlassToCam.Unit:Dot(Normal))) --Projection of glass to camera to glass normal
	local ProjToCamera = GlassToCam-Projection

	local OffsetMag = (ProjToCamera.Magnitude * FocalDisance)/(FocalDisance + Projection.Magnitude) --Get distance to line intersection by similair triangles
	local Offset = ProjToCamera.Unit * OffsetMag

	return Offset
end

local function UpdateSightPosition(Sight,Offset) --My solution to converting the offset into a Udim2 because I have little clue how they work
	
	
	local StudX = Sight.Size.X
	local StudY = Sight.Size.Y

	local Reticle = Sight.SurfaceGui.Frame.Reticle

	Reticle.Position = UDim2.new(Offset.X/StudX,500,Offset.Y/-StudY,500)


end

local TestSight = workspace.System.Sight


while true do
	UpdateSightPosition(TestSight,GetSightOffset(TestSight))
	game:GetService("RunService").RenderStepped:Wait()
end

Hello!
I think the problem you were encountering was due to the original position of the image.
In my workspace, I have the decal in the center of the glass.

You fixed this by offsetting it by 500 pixels to be in the center of the part, which works in this case, but if you wanted to do the same thing on another part with a different size the 500 pixels would manually have to be changed.
Just a heads up in case you weren’t aware, and in case anyone else sees this.

I’m glad I could help you with this, I’m excited to see where your game goes!