Dealing with Unity UI Hierarchy

Jordy Henry "
Return of the Jordy
3 min readOct 31, 2018

As an indie developer, besides coding I’m always on a discovery journey, looking for the workflow that better fits my daily routine. With the UI is not different, working with Canvas can become very complex as it’s purpose and functionalities increases. One of the reasons for this, is that in Canvas, we have to group objects together all the time, to make animations work or to set anchors properly, besides, a lot of native components of the Unity UI add many levels of depth in the Hierarchy.

ಠ_ಠ

So its easy to our Hierarchy quickly looks like one of those old parchments that unrolls forever.

Looking at this problem, and motivated by the fact that some nights ago I wrote a little script related on this, I’ll share my workflow when dealing with Unity UI, hope it helps =)

CLEANING THE HIERARCHY

First of all, inside my Canvas I create an ‘Empty GameObject’ and call it ‘Container’, this way I can use the same Canvas for different subjects. This may come handy when your Canvas needs to keep alive between multiple scenes, this way you can have multiple containers, each one named after those scenes.
Inside my container I create another empty objects, as different screens of the Canvas, and then inside each screen object, I put all the components needed for that screen to work properly.

NOTE : All my ‘Container’ and ‘Screens’ objects anchor positions, stretch vertical and horizontally the parent, this way we configure inner components as we usually do if working directly in the canvas.

TIME TO CODE SOME EXTENSIONS

So our Hierarchy looks pretty organized by now, but we still have a problem. As we know the order the objects are drawn in the Canvas respect their order in the Hierarchy, which means we will always see the last item, in the game view. If we need to change the font color in some Text inside ‘How To Play’ screen, we need to disable all the screens underneath it.

When editing or building a Canvas we switch between screens all the time to make adjustements. You can use the ‘Alt + Shift + A’ shortcut, that toggle the enabled state of the selected object in the Hierarchy. But we are coders, if we see a task that can be automated by code, we take the shot.

Me with my ‘IndexOutOfRangeException’ machine gun …

Lets create a new script and drag it to the ‘Container’ of our Canvas. I proudly name it as ‘UIFocusMode.cs’.
This script will be responsible to check if the object that we select on Hierarchy belongs to any of ours screens, and if it does, the script will only keep this screen active in the Hierarchy, that way we can see it in the game view instantly.

To get the selected object in the Hierarchy, Unity provide us the Selection class, we will use the ‘activeTransform’ variable, and the delegate ‘selectionChanged’ to run our method everytime something is selected in the inspector.

So here comes the trick part, to make this work we have to find which ‘Screen’ the selected object belongs to, as we know all the screens are child of the Container, so if we find a way to walk in the Hierarchy from the selected object to the container and keep track of how many steps were took in the proccess, we can access the ‘Screen’ using the same logic but limiting the steps to ‘stepsTaked — 1’.

Transform _target = Selection.activeTransform;
Transform _container = this.transform;
int steps = 0;
//Calculating steps from container
while(_target != _container)
{
//Walking upwards in the hierarchy
_target = _target.parent;
steps++;
};
Transform _screen = Selection.activeTranform;
for(int i = 0; i < steps - 1; i++)
_screen = _screen.parent;
_screen.gameObject.SetActive(true);

Also as we’re using this in editor, and using classes derived from “UnityEditor”, we need to include ‘ExecuteInEditMode’ call, so the script runs in editor, and wrap our code in a ‘Platform depedent compilation’ if statement , that way we dont have any problem when building our game.

RESULT

Working like a charm

FINAL NOTES

Obviously the script has more code than that, like some security checks to avoid the “Null Reference Exception” pit. I exposed all this checks as bool variables in the script so you can trigger a “Enable All Screens” function in some cases, that way the Canvas returns to its original state, and you can shape the behaviour to what better fits your flow. The full code is available here :

https://gist.github.com/jordyhenry/ca2823705cb39c0c965fdf1cd3b3c19d

I know that this is a very specific case, but it has increased a lot my productivity, and its a great case to expose some concepts as ‘Selection’ class or ‘Platform dependent compilation’.

So if you reached here and have some sugestions or better workflows over Unity UI, or some adjustment to the script, please contact me =)

--

--