I have some code which needs to execute after the layout of a VisualElement has been calculated. VisualElement.schedule.Execute only works sometimes (perhaps another bug), so I decided to register a callback to the CustomStyleResolvedEvent like this:
Problem is: It never runs. This might also be related to why VisualElement.schedule.Execute only has the layout calculated sometimes. Anyways, this is quite a problem as this leaves me with no reliable way of scheduling code to when the layout of an element has been calculated.
Got a new similar use case where the element where I need the layout to be calculated is being modified (adjustment). Using GeometryChangedEvent creates errors about recursive layout. Any ideas?
Layout update is struggling to process current layout (consider simplifying to avoid recursive layout): VisualElement PanelSettings (x:0.00, y:0.00, width:1920.00, height:1080.00) world rect: (x:0.00, y:0.00, width:1920.00, height:1080.00)
UnityEngine.UIElements.UIElementsRuntimeUtilityNative:UpdateRuntimePanels ()
This log happen when a recursive layout loop is detected.
In your case my guess is that in your GeometryChangedEvent callback you do the adjustment to the layout which trigger a new layout pass. This send another GeometryChangedEvent and then more adjustment are made in the callback which trigger another layout pass and so on until you get the “Layout update is struggling to process current layout” message.
I still wonder why CustomStyleResolvedEvent is/was never called? Even if one could work around this issue, I suspect this should be considered a bug or not?
CustomStyleResolvedEvent is only sent when an element is matching any custom style. A custom style property is one that is prefixed with “–”. It can also be used as a variable.
I know the page, but it doesn’t talk about the event
Do I get this right? With “an element is matching any custom style” you mean:
For an element to receive the CustomStyleResolvedEvent, it needs to have, e.g., a class applied which references a custom style property (--custom-property)? And if it receives the event, it has access to all defined custom properties? Or only the one that is applied to it?
How can I access the value of an arbitrary custom property form C# then? E.g., something like --my-default-border-width
I’d suggest being cautious in using GeometryChangedEvent. It seems to have some sort of floating point issue under certain circumstances which makes it get called multiple times during rendering. This can trigger the “Layout update is struggling to process current layout” error.
Also, I was curious about CustomStyleResolvedEvent but I don’t see it documented anywhere on Unity - Manual: Event reference
This is probably due to the GeometryChangedEvent callback modifying the element layout which will trigger a new layout pass and potentially a new GeometryChangedEvent leading to a loop of layout calculation + GeometryChangedEvent.
Right, but in enough cases, Unity will temporarily change the element’s size during its render process when it probably shouldn’t. Namely when it’s inside of a flex container that is changing sizes. Even if the element won’t end up changing size this event gets triggered because the size gets changed temporarily for some reason.
My solution has been to UnregisterCallback, change the container size, and then RegisterCallback. It feels clunky though.