Visual Element Scaling Pivot Position

Hi,

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.

Thanks,
-andy.

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.

1 Like

Ahh, ok great. Thanks a lot for the solution @mcoted3d .

Any updates on this? The empty parent solution only works when you work with pixel values.

Can you share more details about what kind of VisualElement configuration causes issues for you?

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.

1 Like

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.

3 Likes

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?

1 Like

We don’t have a public roadmap, but I’ll pass that feedback forward. Thanks!

4 Likes

Any chance this will make the next package release ? :smile:

This would be soooo convenient for animating Visual Elements…

4 Likes

Bump (my last one I promise, I understand that you already have enough pressure from every side :smile:)

Currently investigating a basic custom animation tool, and it’s unfortunate that we cannot (yet :p) modify the pivot.

6935872--814768--AnimationWithDirectSOEditingHD.gif
6935872--814771--AnimationWithEditor.gif

Should be 2021.2 :slight_smile:

https://discussions.unity.com/t/827168

1 Like

Crossing fingers to have something at least in C# side before 2021.2 in the package

The parent hack workaround won’t be appreciated by my colleagues (increasing again risk of us dropping UITK)

It should come to 2021.2 alpha over the next months, along with a few other improvements, if everything goes according to the plan. :slight_smile:

4 Likes

Thanks for the visibility :slight_smile:

@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.

3 Likes

Thank you for the snippet and the idea :slight_smile:

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:

UIDocument.rootVisualElement.transform.scale

Yes, it is in 2021.2! You can look at this way overdue announcement thread:

You can set it with
visualElement.style.transformOrigin = new TransformOrigin(Length.Percent(100), 0, 0));

1 Like

You can also set the value in the UI bulder/USS instead of code if it always needs to scale around the same position.