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

How can we "attach" script to our UXML / USS at runtime?

Discussion in 'UI Toolkit' started by Kaiymu_, Apr 20, 2020.

  1. Kaiymu_

    Kaiymu_

    Joined:
    Jun 1, 2016
    Posts:
    47
    Hello,

    I have a question using UIRuntime.
    How is that possible that on runtime I can display page A and when I click on a button, page B displays itself with element attached to it.

    Basically my question is that previously on UGUI, you would attach script to Gameobjects that would be created / destroyed so the behavior would only occur for that specific UI.

    But with UIToolkit I don't quite understand how a script can "attach" to a specific UXML / USS.

    Right now I have a script on my scene that fill a list of items. When I click on a item, I want page B to be displayed with it's own "behavior" being called. But I don't see any way of doing that.

    I don't know if it's quite clear!

    Thank you everyone.
     
  2. Kaiymu_

    Kaiymu_

    Joined:
    Jun 1, 2016
    Posts:
    47
    Hello.

    What I mean by that is exactly doing here


    When pressing play. All the UI changes.
    Or when loosing / Winning the game.

    Thanks.
     
  3. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    771
    Hello,

    Given the current capabilities we have access to today this is not really possible, or at least not as easily as attaching MonoBehaviour in the UI Builder.

    Generally you'd need to retrieve elements separately with a uQuery from your script attached on the GameObject holding the Panel Renderer.

    Another approach would be to create a custom VisualElement :
    1. Declare an element deriving from VisualElement
    2. As it should become visible in UI Builder, you can add to the UXML document
    3. When this element get added/removed at runtime you can basically activate/deactivate your event handlers

    You can then have a more simple “top level” script that switches different UI screen either by adding/removing elements from the hierarchy or using style.display = DisplayStyle.None/DisplayStyle.Flex to hide/show elements.

    Then your custom element could react to that using events:

    Something like:
    Code (CSharp):
    1. class MainMenu : VisualElement
    2. {
    3.     public new class UxmlFactory : UxmlFactory<MainMenu, VisualElement.UxmlTraits> {}
    4.  
    5.     public MainMenu()
    6.     {
    7.          RegisterCallback<AttachToPanelEvent>(Enable);
    8.          RegisterCallback<DetachFromPanelEvent>(Disable);
    9.          RegisterCallback<GeometryChangedEvent>(LayoutChange);
    10.     }
    11.  
    12.     private void Enable(AttachToPanelEvent evt)
    13.     {
    14.          // interact with children for example to register more callbacks
    15.          this.Q<VisualElement>(className: "some-child");
    16.     }
    17.  
    18.     private void Disable(DetachFromPanelEvent evt)
    19.     {
    20.          // interact with children for example to unregister callbacks
    21.          this.Q<VisualElement>(className: "some-child");
    22.     }
    23.  
    24.     private void LayoutChange(GeometryChangedEvent evt)
    25.     {
    26.          if (evt.newRect == Rect.zero)
    27.          {
    28.              // Likely, DisplayStyle was set to None
    29.          }
    30.          else if(evt.oldRect == Rect.zero)
    31.          {
    32.              // Likely, DisplayStyle was set to None and is back to Flex
    33.          }
    34.        
    35.     }
    36. }
     
    Last edited: Apr 27, 2020
  4. Kaiymu_

    Kaiymu_

    Joined:
    Jun 1, 2016
    Posts:
    47
    Hello Antoine

    Thanks for the reply! I'm going to try that on the upcoming days and hopefully will test if it's working or not!
    Have a great day,