Recently I have been working a lot with Unity’s UI system. The editor itself is a great tool, I’m able to quickly make what I want and have it respond to changes in screen sizes without too much effort. Trying to control it programatically, trying to drive a completely dynamic layout, however is a lot more painful. I can’t wait for the new UIElements system to be usable in-game.
It’s not that it’s buggy - it’s not - it’s that the information in the editor
window is not transferable to code. I can’t set the
localPosition of an
object and expect it to be where it would be if I set the same value in
(what looks like) the same places in the editor.
So we sensibly head to the documentation. On the whole, Unity’s manuals and
documentation (and all their other resources) are great, but the docs for the
components in the UI system can be a little …vague. For instance
RectTransform.pivot is documented simply as
The normalized position in this RectTransform that it rotates around
Hmmm. I’m not sure what that’s supposed to mean. This isn’t even complete. A pivot is the origin point from which all transformations take place - including rotation but also scaling and translation. This means the position of an object within its parent relies on its pivot, we can prove this with a little experimentation.
The image shows 5 game objects with different pivots, each has a x and y set to zero in the editor. As you can see, the pivot how the object is positioned within its parent and in which direction the object scales. It would also describe the point on the object around which it was rotated.
This means you need to take the pivot into account when trying to position an object from code - when building a custom layout component, for instance. As an example, we could take a custom layout that places items in the middle and corners of itself, like in the image above. We could control the pivots from the layout, and it would work out of the box, but we could do better.
In Unity, (0, 0) is the bottom left corner in the UI system. Setting the pivot of an object has the effect of moving the object away from the bottom corner of its parent, it also moves the point from which the width and height of the object extend. By ‘undoing’ these two effects we can then position the object where we want, regardless of the pivot.
This adds an extension method to
RectTransform. Calling this on an object
with (0, 0) places the object in the bottom left corner of the parent, no
matter the pivot value of child. Calling it with
(parentWidth-childWidth, parentHeight-childHeight) places it in the top right
Example project can be found on github.