Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug CustomStyleResolvedEvent Never Called

Discussion in 'UI Toolkit' started by Nexer8, Sep 3, 2021.

  1. Nexer8

    Nexer8

    Joined:
    Dec 10, 2017
    Posts:
    271
    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:
    Code (CSharp):
    1. element.RegisterCallback<CustomStyleResolvedEvent>(e => Debug.Log(element.resolvedStyle.width));
    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.

    This happens on version 2021.2.0b9.
     
  2. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    771
    Why not use GeometryChangedEvent ?
     
  3. Nexer8

    Nexer8

    Joined:
    Dec 10, 2017
    Posts:
    271
    Totally forgot about that! Thanks!
     
  4. Nexer8

    Nexer8

    Joined:
    Dec 10, 2017
    Posts:
    271
    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 ()
     
    Last edited: Oct 1, 2021
  5. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    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.
     
  6. seyfe

    seyfe

    Joined:
    May 10, 2019
    Posts:
    74
    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?
     
    Nexer8 likes this.
  7. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    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.

    You can refer to this page for more information.
     
    Nexer8 and Alex-Chouls like this.
  8. seyfe

    seyfe

    Joined:
    May 10, 2019
    Posts:
    74
    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`
     
    MostHated likes this.
  9. tonytopper

    tonytopper

    Joined:
    Jun 25, 2018
    Posts:
    225
    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 https://docs.unity3d.com/2022.2/Documentation/Manual/UIE-Events-Reference.html
     
  10. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    When the element receives the event it has access to all the custom properties that are applied to this element.

    You can register a `CustomStyleResolvedEvent` callback on the element that `--my-default-border-width` property is applied to.
     
  11. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    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.
     
  12. tonytopper

    tonytopper

    Joined:
    Jun 25, 2018
    Posts:
    225
    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.