When I change the anchor point of the frame, it moves. However, the position remains the same except for the absolute position. The problem is that I cannot set the absolute position as it’s read only. How then I can keep the original position of my GUI when changing the anchor point?
I already tried the solution from this post but did not work and instead it just moved my GUI out of the screen.
So far I managed to write this:
function Util.SetAnchorPointWithoutMoving(gui: GuiObject, desiredAnchorPoint: Vector2)
-- Save previous position
local oldAP = gui.AbsolutePosition
-- Set the anchor point
gui.AnchorPoint = desiredAnchorPoint
-- Correct the position
local newAP = gui.AbsolutePosition
local relative = oldAP - newAP
gui.Position += UDim2.fromOffset(relative.X, relative.Y)
end
However, for some reason the GUI still moves by like 0.5 pixels.
I am unsure to why it is important for your Ui to maintain the same position when adjusting the anchor point, but I am pretty sure that this is something you cannot change.
0.5,0.5 means that the position you previously set it to is now the exact Center of your Frame.
By default (0,0) the position is TopLeft, so the Frame is actually “sticking out” 90 pixels to the right and 80 pixels below its position.
So if you want to change it to 0.5,0.5 and maintain your visual position, you need to add half the size of your Frame to the position. So position would be along the lines of:
Edited the function to make it so that it will work with any AnchorPoint now and now just /2 for 0.5,0.5
Edit: to clarify why your original function doesn’t work, AnchorPoint does NOT change the position of a GuiObject. It just changes where it’s rendered from. By default it renders the pixels of your GuiObject from the Top Left. In this case, the center is where it’s rendered from.
I made one mistake of leaving desiredAnchorPoint.Y in the X side of the offset calculation, but besides from that, there should be no reason it’s doing that. What anchorpoint are you setting? 0.5,0.5?
Edit: Pushing it left should be happening, but pushing it up…? You make it sound like the Y is going down. Or is the frame itself moving down?
Since you hearted this it brought it back to my attention so I tested it.
The green part is where it was first.
It tweens to AnchorPoint 0.5,0.5 first,
then it tweens to the solution I gave you.
-- Same code for position, just changed it from TweenPosition
gui.Position = UDim2.fromOffset(oldAP.X + (gui.AbsoluteSize.X * desiredAnchorPoint.X), oldAP.Y + (gui.AbsoluteSize.Y * desiredAnchorPoint.Y))
I did use your function correctly, but it doesn’t work as intended. In the meantime someone figured out slightly different way to approach this problem and their solution works almost perfectly but there are few cases where it doesn’t work as well.
local originalPosition = frame.AbsolutePosition
local function setAnchorPoint(gui, desiredAnchor)
local anchorInfluence = desiredAnchor * gui.AbsoluteSize
gui.AnchorPoint = desiredAnchor
gui.Position = UDim2.fromOffset(anchorInfluence.X + originalPosition.X, anchorInfluence.Y + originalPosition.Y)
end
Yes, I want to have an option in my plugin that will keep the position of the anchor point as sometimes I have an GUI element perfectly positioned but with incorrect anchor point, and when I change the anchor point it’s really annoying to have to reposition the GUI element back to where it was.
Here is my complete solution (which includes support for viewport when parent is not available).
--!strict
local Workspace = game:GetService("Workspace")
local Util = {}
-- PS stands for position and size
function Util.GetParentPS(gui: GuiObject): (Vector2, Vector2)
local parent = gui.Parent
if parent then
if parent:IsA("GuiObject") then
return parent.AbsolutePosition, parent.AbsoluteSize
end
end
return Vector2.zero, Workspace.Camera.ViewportSize
end
function Util.SetAnchorPointWithoutMoving(gui: GuiObject, desiredPoint: Vector2)
local parentPosition, parentSize = Util.GetParentPS(gui)
local childSize = gui.AbsoluteSize
local childPosition = gui.AbsolutePosition
-- Calculate the relative position
childPosition = childPosition - parentPosition
local correctionOffsetX = childSize.X * desiredPoint.X
local correctionOffsetY = childSize.Y * desiredPoint.Y
local correctedPosition = UDim2.fromScale(
(childPosition.X + correctionOffsetX) / parentSize.X,
(childPosition.Y + correctionOffsetY) / parentSize.Y
)
gui.AnchorPoint = desiredPoint
gui.Position = correctedPosition
end
return Util