I’m animating a Visual Element hierarchy on screen by adjusting its transform.scale property via the Scheduler API. This causes the visual element to scale around its origin position in the top left corner. How can I adjust the pivot position around which the visual element will scale? This is in order to, for example, scale the element around its rect’s center. In Unity UI this can be achieved by adjusting the RectTransform’s pivot position.
You cannot change the pivot at this time, but we have plans to revise this in the future. So in the meantime, the only way to change the pivot of a transform is to add an intermediate VisualElement.
For example, add your VisualElement to an empty parent, change the position of the element so that it is centered relative to its parent, then scale the parent.
For example if you want an element to be 50% the width and 50% of the height of its container, but the container is an empty that you use as pivot, then 50% of 0 is going to be 0. Being able to adjust the origin would make us not need the empty, and the problem would be fixed. This also allows for buttons to change size on hover without complications because it’s position is it’s center. In general it just makes it easier to handle positioning rotation and scaling of VisualElements without having to do all sorts of trickery.
100% agree. I can’t tell exactly when this feature will be implemented, but it is quite high on our todo list. In the meantime, you’ll have to use the parent hack, unfortunately.
Great to hear! Also, is there a productboard similar to the one for the scriptable render pipelines where we can see what is being worked on, what has been implemented and what is under consideration?
@Midiphony-panda - I make a new class anytime I want to make some extension methods, so I’ve got the following class:
using UnityEngine;
using UnityEngine.UIElements;
public static class VisualElementExtensionMethods
{
public static void Rotate(this VisualElement item, float angleDegrees)
{
// Get the x/y location of the center note - these are constant unless the parent rescales; i.e., they don't change with rotation.
float x0 = item.contentRect.center.x;
float y0 = item.contentRect.center.y;
// Convert Cartesian to Polar
float r = Mathf.Sqrt(x0 * x0 + y0 * y0);
float theta0 = Mathf.Atan2(y0, x0);
// Calculate the location of the center of the VisualElement after rotating
// Note: The rotation you want is *in addition* to the "default" polar angle from origin to the center
float x = r * Mathf.Cos(theta0 + (Mathf.Deg2Rad * angleDegrees));
float y = r * Mathf.Sin(theta0 + (Mathf.Deg2Rad * angleDegrees));
// Actually do the requested rotation
item.transform.rotation = Quaternion.Euler(0f, 0f, angleDegrees);
// Finally, rotation happens about the upper-left corner of the VisualElement, so you need to shift the position
// to get the rotated center to be coincident with the un-rotated center.
float xDelta = x0 - x;
float yDelta = y0 - y;
item.transform.position = new Vector3(xDelta, yDelta, 0f);
}
}
Now I can do stuff like myVisualElement.Rotate(90) and it’ll rotate about its center. Hope this helps! Had the same problem so I figured I’d post my answer here for everyone to use. You were asking about it specifically so I figured I’d tag you in the response.
Is this pivot feature available in 2021.2.1f1? We have a complex hierarchy of various elements and scaling is centered to an unknown position. Sometimes, elements goes out of the screen while scaling, we need to control the position of the root. We apply the scale this way: