Skip to content

Instantly share code, notes, and snippets.

@blinkybool
Created December 3, 2021 04:01
Show Gist options
  • Save blinkybool/c6c881e9d23ecf0c4a195bd72f185423 to your computer and use it in GitHub Desktop.
Save blinkybool/c6c881e9d23ecf0c4a195bd72f185423 to your computer and use it in GitHub Desktop.
Roblox Gui Positioning (accounts for IgnoreGuiInset)
-- The AbsolutePosition of any object is not the same as it's actual pixel
-- coordinates on the screen. AbsolutePosition is relative to the pixel
-- coordinate (0,36), so the top left pixel actually has AbsolutePosition
-- (0,-36)
-- To place a GuiObject somewhere, you need to set its Position property.
-- The resulting AbsolutePosition depends on whether IgnoreGuiInset is
-- checked on the screen gui that the GuiObject lives in.
-- A Position value has both a scale value and offset value
-- The below discussion is treating GuiObject.Y as if it's just an offset
-- value, since these are pixel units, not proportions of the screen.
-- If IgnoreGuiInset is off then
-- GuiObject.AbsolutePosition.Y = GuiObject.Position.Y
-- If IgnoreGuiInset is on then
-- GuiObject.AbsolutePosition.Y = GuiObject.Position.Y - 36
-- So if we have a target value for GuiObject.AbsolutePosition.Y
-- and IgnoreGuiInset is on, then we should set the GuiObject.Position.Y
-- to +36 more than the target value
-- In terms of actual pixel coordinates... (where objectPixelY is the actual
-- y-coordinate of the object on the screen)
-- If IgnoreGuiInset is off then
-- objectPixelY = GuiObject.Position.Y + 36
-- If IgnoreGuiInset is on then
-- objectPixelY = GuiObject.Position.Y
-- So if we want the anchor point of our object to appear at some pixel
-- coordinate x,y, and IgnoreGuiInset is off, then we should set
-- GuiObject.Position.Y to y-36.
-- Returns the correct value for GuiObject.Position so that it will appear
-- at the given absolutePosition
-- The IgnoreGuiInset property of the screen gui should be passed as the
-- second argument.
local function PositionFromAbsolute(absolutePosition, ignoreGuiInsetChecked)
if ignoreGuiInsetChecked then
return UDim2.new(0, absolutePosition.X, 0, absolutePosition.Y + 36)
else
return UDim2.new(0, absolutePosition.X, 0, absolutePosition.Y)
end
end
-- Returns the correct value for GuiObject.Position so that it will appear
-- at the given pixel coordinates on the screen.
-- The IgnoreGuiInset property of the screen gui should be passed as the
-- second argument.
local function PositionFromPixel(pixelX, pixelY, ignoreGuiInsetChecked)
if ignoreGuiInsetChecked then
return UDim2.new(0, pixelX, 0, pixelY)
else
return UDim2.new(0, pixelX, 0, pixelY-36)
end
end
---------------
--Example Usage
---------------
UserInputService = game:GetService("UserInputService")
ScreenGui = script.Parent
-- The x,y values passed when MouseMoved is fired are actual pixel coordinates,
-- so we use PositionFromPixel to place the Frame called ScreenGui.FromPixel
-- at the cursor
ScreenGui.Frame.MouseMoved:Connect(function(x,y)
ScreenGui.PixelPos.Text = "Pixel Position: "..x..", "..y
ScreenGui.FromPixel.Position = PositionFromPixel(x,y, ScreenGui.IgnoreGuiInset)
end)
-- UserInputService.InputChanged provides an inputObject, which has a .Position value.
-- This should be treated as an AbsolutePosition, so we use PositionFromAbsolute
-- to place the Frame called ScreeGui.FromAbs at the cursor
UserInputService.InputChanged:Connect(function(input, gp)
if input.UserInputType == Enum.UserInputType.MouseMovement then
ScreenGui.AbsPos.Text = "AbsolutePosition: "..input.Position.X..", "..input.Position.Y
ScreenGui.FromAbs.Position = PositionFromAbsolute(input.Position, ScreenGui.IgnoreGuiInset)
end
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment