How to change anchor point of UI element while keeping the same position?

I’m making a plugin that sets all of the descendants of a screenGUI’s anchor point to 0.5,0.5 and convert their offset to scale.

However when I change the anchor point it also changes the position of the ui, is there some way to keep the same position while changing the anchor point?

1 Like

The AnchorPoint property changes position like this:

--assumes:
----viewportsize is defined
----AbsolutePosition is not readonly
local sz = uiobj.AbsoluteSize
local anchpnt = uiobj.AnchorPoint
local pos = uiobj.Position
uiobj.AbsolutePosition = Vector2.new(
    pos.X.Scale * viewportsize - anchpnt.X * sz + pos.X.Offset,
    pos.Y.Scale * viewportsize - anchpnt.Y * sz + pos.Y.Offset
)

What you want to have is this:

--assumes oldap is defined
pos.X.Scale * viewportsize - oldap.X * sz + pos.X.Offset,
pos.Y.Scale * viewportsize - oldap.Y * sz + pos.Y.Offset

But you have this:

--assumes oldap is defined
pos.X.Scale * viewportsize - newap.X * sz + pos.X.Offset,
pos.Y.Scale * viewportsize - newap.Y * sz + pos.Y.Offset

Here it makes sense to change the offset, so you just do this:

--assumes oldap and newap are defined
uiobj.Position -= Udim2.fromOffset(oldap.X - newap.X, oldap.Y - newap.Y) * sz

The difference is added so it should have the same AbsolutePosition.

I’ve edited this reply to fix a few issues (like using + instead of - when putting AnchorPoint into the expression)

2 Likes

Unfortunately Udim2s are ReadOnly so you have to change the position itself, and also, that logic won’t work. If the anchorpoint’s X was 0.5, it should go left exactly its X size halved many pixels, but your code will make it go right.

He wants to change Anchorpoint without changing position, that is what my code does, Udim2 arent read only?

@cnr123451 is right u can’t change Udim2s. This:

will throw this error: Scale cannot be assigned to. So you should set position like this:

Ui.Position = UDim2.fromScale(Ui.Position.X.Scale + 0.5 , Ui.Position.Y.Scale + 0.5)

Btw I think that your method doesn’t work, I don’t have access to my pc so I can’t test it.

I was talking about what would happen if I set an anchorpoint. I think you confused Scale which when multiplied by the viewport size gives the actual position with Offset multiplied by the UIObject’s size.

i meant

Ui.Position = Udim2.new(Ui.Position.X.Scale += anchorPointX)

and so on, my bad, i explained it incorrectly

That’s incorrect either.

char limit

1 Like

I still don’t understand this: If I were to change the anchor point from 0 to 1 when the position is 0, 0, wouldn’t your code make it go to the right?

by the way you probably wanted to use + instead of += which (for whatever reason) is not an operator plus it modifies a read only value

Thanks for the info, however how can I make this work with scale instead of offset? Or does it matter?

Instead of this, you would do something like this:

local pos = Vector2.new(oldap.X - newap.X, oldap.Y - newap.Y) * sz / viewportsize
uiobj.Position += Udim2.fromScale(pos.X, pos.Y)
--Assuming viewportsize is defined, you can get that by doing workspace.Camera.ViewportSize

IMPORTANT: Only do that if you want to have the anchorpoint set accordingly to the studio’s camera (which is probably what you want to do but just wanted to say that)

By the way you can get the viewport size using this

1 Like

This currently does not work, it just makes the ui object disappear. Also I’m not sure if using the workspace camera’s viewport size will work in all cases, as I have added support for nested objects(for example a frame as a child of a frame)

Code:

local oldAP = v.AbsolutePosition
							
v.AnchorPoint = Vector2.new(0.5,0.5)
							
local newAP = v.AbsolutePosition
							
local pos = Vector2.new(oldAP.X, newAP.X, oldAP.Y, newAP.Y) * v.AbsoluteSize / workspace.CurrentCamera.ViewportSize
							
v.Position += UDim2.fromScale(pos.X, pos.Y)

By “AP” I meant AnchorPoint, not AbsolutePosition.

My mistake, now it doesn’t go off and disappear, but it still moves a bit to the right when I set it unfortunately.

You provided new arguments each time, the last two are discarded. Subtract them instead like this:

local pos = Vector2.new(oldAP.X - newAP.X, oldAP.Y - newAP.Y) * v.AbsoluteSize / workspace.CurrentCamera.ViewportSize
1 Like

It moves to the right and up now :confused:

I sometimes suck at coding, sorry for that.

Could you try the Offset solution and check if it works?

v.Position += UDim2.fromOffset(oldAP.X - newAP.X, oldAP.Y - newAP.Y) * v.AbsoluteSize

Also try turning the += into -=, though I’d be surprised if that works.
wait i think that change will make it work

1 Like

attempt to multiply a Vector2 with an incompatible value type or nil, maybe instead I should listen for when a gui object is added and setting the anchor point then instead?

you need to change v.AbsoluteSize to Udim2.fromOffset(v.AbsoluteSize.X, v.AbsoluteSize.Y) but I think you should first go back to the Scale solution and try this:

For example if we increase the anchorpoint, we will get a negative value from the summation and make it go towards the left (which is not what happens but yeah) so we should instead do subtraction

1 Like

It works now! Still one final boss though, nested frames don’t have the proper position. I’m guessing this is related to the absolute size and position of the parent frame because I had to make these adjustments to get offset to scale to work for these.