In this post, I talk about setting the anchorMin
and anchorMax
of a RectTransform
to the same value and directly assigning the anchoredPosition
and sizeDelta
. This is going to expand on that to mimic using GUIs APIs that have an origin on the top left.
A lot of traditional GUI APIs have a coordinate system where the top left is the origin. [1][2] Even Unity’s legacy IMGUI (the GUI system that Unity’s Inspector and Editor scripts still use) has a top-left origin convention. Unity’s current main GUI system (UGUI) goes the other way and makes the bottom left the viewport origin to match the coordinate convention of its 3D content. This also means moving content in +Y moves GUI content up instead of down. But, what if you really want to have the top-left as your origin and work like a traditional UI?
To do that:
- For every
RectTransform
in the hierarchy, set theanchorMin
andanchorMax
toVector(0.0f, 1.0f)
- For every
RectTransform
in the hierarchy, set thepivot
toVector(0.0f, 1.0f)
. - Set the
sizeDelta
to the pixel dimensions you want the UI’s rectangle to be. - Set the
anchoredPosition's
position, except with a negated Y.
The first two items set up the coordinate frame of the RectTransform
to be anchored to the top left or itself, and its parent. Then you can place stuff from from the top as your origin as long as you remember to negate the Y component of the position.
Example
So if I was writing something in PlatformSDK (or wxWidgets or MFC, or X11/Motif, or whatever IOS, Mac or Andro… you know – etc) to create a UI element:
// Windows Platform SDK (with C) to create a button and assign it a position and size // Allocate the button HWND hwndBtn = CreateWindow( L"BUTTON", L"Example", BS_DEFPUSHBUTTON|WS_CHILD|WS_VISIBLE, 0,0,0,0 // Leave empty so we can change it with a call parentHwnd, NULL, hInstance, NULL); // Set the button 30 pixels from the left, and 50 pixels from the top // With a size of 200px x 20x SetWindowPos(hwndBtn, HWND_NOTOPMOST, 30, 50, 200, 20, SWP_NOZORDER);
I can translate it into Unity with something like
// Unity C#, creating a button and assining its position and size similar to tradtional // dialog programming. // Create GameObject go = new GameObject("Button", typeof(UnityEngine.UI.Button), typeof(UnityEngine.UI.Image)); go.transform.SetParent(parentGO.transform, false); RectTransform rt = go.GetComponent<RectTransform>(); //Adding an Image forced it to already have a RectTransform // Setting pivot and anchors to top left (<0.0, 1.0>) rt.anchorMin = new Vector2(0.0f, 1.0f); rt.anchorMax = new Vector2(0.0f, 1.0f); rt.pivot = new Vector2(0.0f, 1.0f); // Setting the button's position to 30 pixels from the left, and 50 pixels from the top rt.anchoredPosition = new Vector2(30.0f, -50.0f); // Set the button's pixel dimensions rt.sizeDelta = new Vector2(200.0f, 20.0f);
This helps take old GUI coding knowledge and algorithms for dialogs and translate them into Unity without spending too much cognitive effort on going back-and-fourth between conventions. Very often when (re)implementing/porting dialog and UI libraries into Unity that I’ve made in the past, I’ll set up all the data structures and calculations to be based off the top left (how I’m used to for traditionally coding dialogs) and simply set the position to an inverted Y at the very end.
– Stay strong, code on. William Leu
Explore more articles here.
Explore more articles about Unity here.