Updating UI if children RectTransform has changed

Hi, I’m struggling for at least 1.5h to find a solution to update my custom LayoutGroup class to update itself if its Childs rect transforms update.
Essentially I’m building a content size fitter that works, and it does… at least as long as its children don’t update.

It needs to be working in editor and runtime. Unity is doing it. I looked at their decompiled layout elements, but I can’t see anything special there.

I tried:

OnRectTransformDimensionsChange();
CalculateLayoutInputHorizontal();
CalculateLayoutInputVertical();
SetLayoutHorizontal();
SetLayoutVertical();
OnCanvasGroupChanged();
OnCanvasHierarchyChanged();

I don’t know anymore. This is so basic. Basically every ui element must do something if their children change, this can’t be so hard!

PS: It’s basically the same as resizing the game window ever so slightly… This will update my functions, since CalculateLayoutInputHorizontal() is called. I need this when the children update. But adding events to every single of them feels like the worst approach that I could go for…

I would use some type of event to inform the ui structure of the change. Modify the rect extents through your own layout component, that in turn informs its parent layout group component that it has changed.

1 Like

I thought about the event stuff, but I would have to go through all the children and add an event listener. Keep track and subscribe, unsubscribe if something changes or gets destroyed or disabled. For now I do the calculations in Update() which seems very bad, since most of the time the size won’t change… :S

another alternative would be to monitor the unity mouse down event for the root window, so you get a notification when the user has clicked inside the window, and on mouse down store all child rect sizes at the start of the mouse down event, as well as initiate a coroutine that monitors all sizes until the mouse event is released. you could check if the mouse event is at the border of a window, and if it isn’t , no need to do anything.

Are you implementing the ILayoutGroup interface?

This video talks about how layout groups get “dirtied” so that they know to update:

Adding events to every single one of your children would probably be more performant (though it would also be more work).

I’m implementing the ILayoutSelfController, since I want to control it’s own layout / size. But there doesn’t seem to be an event that has the right notification if any children transforms have changed.

I know this video and watched it 2 times already :stuck_out_tongue: had to find it some weeks ago, to convince my team to not use animators in our UI :smile: that was a close one! But I don’t remember that the video talks about stuff that would help me fix this issue ^^
We are keeping the dirty solution until we run into problems. At worst I need to add components to every child with an event sender, which seems dirty as-well :smile:

What has a mouse down to do with resizing? Maybe you are thinking of another use case that I actually encounter.

When the video shows the source code for how layout elements look for parent layout groups to dirty, they specifically look for components with the interface ILayoutGroup. So if you want your component to be notified by the standard existing UnityEngine mechanisms, I presume it needs to implement that interface.

There is perhaps an argument that ILayoutSelfController is a better fit for your concept in terms of the English description of what it’s meant to do, but the engine does not care about the English, it’s going to obey the code.

1 Like