- Home /
Set a RectTranform's pivot without changing its position
Is there a way to change a RectTransform's pivot point without changing its position? If not, does someone know the math I would have to do to simulate this behavior? Thanks in advance!
Answer by jmorhart · Jul 30, 2015 at 05:35 PM
Well, I managed to figure this one out on my own. Implemented as an extension method of the RectTransform class. Currently only works properly for XY axis-aligned objects.
public static void SetPivot(this RectTransform rectTransform, Vector2 pivot)
{
if (rectTransform == null) return;
Vector2 size = rectTransform.rect.size;
Vector2 deltaPivot = rectTransform.pivot - pivot;
Vector3 deltaPosition = new Vector3(deltaPivot.x * size.x, deltaPivot.y * size.y);
rectTransform.pivot = pivot;
rectTransform.localPosition -= deltaPosition;
}
Thanks man! This does not make sense AT ALL! :D But it works. I have spent whole week trying to assign x,y position of RectTransform, also anchoredPosition and it never came to my $$anonymous$$d that it was this simple :)
Awesome, I needed to do just this and was able to drop in your solution with no problems. Thanks!
Note: If you're changing scale at all, you'll need to incorporate that as well:
var scale = rectTransform.localScale;
...
var deltaPosition = new Vector3(
deltaPivot.x * size.x * scale.x,
deltaPivot.y * size.y * scale.y);
Do you know how to implement this method when the RectTransform has been rotated as well? It seems to be a bit more complex and I can't figure it out.
+Props to you dude, solid solution and awesome of you to put it in a method for people to copy paste.
Answer by LiterallyJeff · Aug 24, 2018 at 03:20 PM
Here is a cleaned up version of previous commenters' extension function, which supports scaling & rotation.
/// <summary>
/// Set pivot without changing the position of the element
/// </summary>
public static void SetPivot(this RectTransform rectTransform, Vector2 pivot)
{
Vector3 deltaPosition = rectTransform.pivot - pivot; // get change in pivot
deltaPosition.Scale(rectTransform.rect.size); // apply sizing
deltaPosition.Scale(rectTransform.localScale); // apply scaling
deltaPosition = rectTransform.rotation * deltaPosition; // apply rotation
rectTransform.pivot = pivot; // change the pivot
rectTransform.localPosition -= deltaPosition; // reverse the position change
}
To get this to work I had to replace rectTransform.rotatation
with rectTransform.transform.localRotation
Answer by wck19870829 · Mar 14, 2019 at 08:52 AM
public static void SetPivot(RectTransform target, Vector2 pivot)
{
if (!target) return;
var offset=pivot - target.pivot;
offset.Scale(target.rect.size);
var wordlPos= target.position + target.TransformVector(offset);
target.pivot = pivot;
target.position = wordlPos;
}
Thanks! That was the only solution that worked in my case. Not sure why the previous solutions caused problems in my setup...