How do I tell if a GUI is off the screen

I have a dragging GUI script and I want to tell when the GUI leaves the screen in any way.
Meaning this should be true:
image
And this would be false:
image
My frame is sized and positioned in scale.

The dragging script if you want it
local UserInputService = game:GetService("UserInputService")
local runService = (game:GetService("RunService"));

local gui = script.Parent.Parent

local dragging
local dragInput
local dragStart
local startPos

function Lerp(a, b, m)
	return a + (b - a) * m
end;

local lastMousePos
local lastGoalPos
local DRAG_SPEED = (20);
function Update(dt)
	if not (startPos) then return end;
	if not (dragging) and (lastGoalPos) then
		gui.Position = UDim2.new(startPos.X.Scale, Lerp(gui.Position.X.Offset, lastGoalPos.X.Offset, dt * DRAG_SPEED), startPos.Y.Scale, Lerp(gui.Position.Y.Offset, lastGoalPos.Y.Offset, dt * DRAG_SPEED))
		return 
	end;

	local delta = (lastMousePos - UserInputService:GetMouseLocation())
	local xGoal = (startPos.X.Offset - delta.X);
	local yGoal = (startPos.Y.Offset - delta.Y);
	lastGoalPos = UDim2.new(startPos.X.Scale, xGoal, startPos.Y.Scale, yGoal)
	gui.Position = UDim2.new(startPos.X.Scale, Lerp(gui.Position.X.Offset, xGoal, dt * DRAG_SPEED), startPos.Y.Scale, Lerp(gui.Position.Y.Offset, yGoal, dt * DRAG_SPEED))
end;

script.Parent.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		dragging = true
		dragStart = input.Position
		startPos = gui.Position
		lastMousePos = UserInputService:GetMouseLocation()

		input.Changed:Connect(function()
			if input.UserInputState == Enum.UserInputState.End then
				dragging = false
			end
		end)
	end
end)

script.Parent.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
		dragInput = input
	end
end)

runService.Heartbeat:Connect(Update)

Thanks for any help.

1 Like

define a square, the screen and define 4 points, the corners of the GUI. then just do a point inside box test for all the points and if any of the points are not colliding then your GUI is offscreen

2 Likes

I believe for scale, this should work:

local y = gui.Position.Y.Scale + (gui.Size.Y.Scale/2)
local x = gui.Position.X.Scale + (gui.Size.X.Scale/2)

if y > 1 or x > 1 then
    print("out of screen")
else
    print("in screen")
end
3 Likes

this might work if his drag script changes the scale. but they just change the offset of Y Scale, so Y scale would stay 0

1 Like

Oh, for offset, just simply change the scales to offset and divide the screen size by it.

local y = workspace.CurrentCamera.ViewportSize / (gui.Position.Y.Offset+ (gui.Size.Y.Offset/2))
local x = workspace.CurrentCamera.ViewportSize / (gui.Position.X.Offset + (gui.Size.X.Offset/2))

if y > 1 or x > 1 then
    print("out of screen")
else
2 Likes

That’s not working. For some reason the x and y variables are just INF, INF when I print them.
image

1 Like

Oh, sorry, switch it the other way.

local y =  (gui.Position.Y.Offset+ (gui.Size.Y.Offset/2)) / workspace.CurrentCamera.ViewportSize.Y
local x =  (gui.Position.X.Offset + (gui.Size.X.Offset/2)) / workspace.CurrentCamera.ViewportSize.X

if y > 1 or x > 1 then
    print("out of screen")
else

Also forgot the X and Y in viewport size

1 Like

You’re going to be best off using the AbsolutePosition and AbsoluteSize properties of your guis. Using either scale or offset will ignore any properties of the other when doing the calculations.

Since you said you used scale you could update this to use scale instead, but doing it this way will make it work if you ever add any offsets.

Additionally Roblox’s top bar can mess with the numbers, so you will want to do something like this.

local guiInset = game:GetService("GuiService"):GetGuiInset()
local function isInScreen()
	local pos = script.Parent.AbsolutePosition + guiInset
	return pos.X + script.Parent.AbsoluteSize.X <= game.Workspace.CurrentCamera.ViewportSize.X and pos.X >= 0
		and pos.Y + script.Parent.AbsoluteSize.Y <= game.Workspace.CurrentCamera.ViewportSize.Y and pos.Y >= 0
end

You might find it easier to detect if it’s in a parent frame however. So something like this

local function isInParent(guiObject)
	return guiObject.AbsolutePosition.X >= guiObject.Parent.AbsolutePosition.X and guiObject.AbsolutePosition.X + guiObject.AbsoluteSize.X <= guiObject.Parent.AbsolutePosition.X + guiObject.Parent.AbsoluteSize.X 
		and guiObject.AbsolutePosition.Y >= guiObject.Parent.AbsolutePosition.Y and guiObject.AbsolutePosition.Y + guiObject.AbsoluteSize.Y <= guiObject.Parent.AbsolutePosition.Y + guiObject.Parent.AbsoluteSize.Y
end
3 Likes