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

rootVisualElement is null OnEnable using the built in UIToolkit in 2021.2

Discussion in 'UI Toolkit' started by SteveSync, Mar 3, 2021.

  1. SteveSync

    SteveSync

    Joined:
    Sep 25, 2013
    Posts:
    27
    I recently updated to use the Unity 2021.1.0b6 (EDIT: Made a mistake, it was actually 2021.2.0a6) build (To fix an issue with the UI Toolkit breaking DOTS) and found that the rootVisualElement is now null during the OnEnable methods of my MonoBehaviours that are attached to the UIDocument GameObject.

    Looking through the UnityRoyale example there's the GameScreen which is doing something similar to what I'm doing in my project:

    Code (CSharp):
    1.     [RequireComponent(typeof(UIDocument))]
    2.     public class GameScreen : MonoBehaviour
    3.     {
    4.         private VisualElement cardPanel;
    5.  
    6.         void OnEnable()
    7.         {
    8.             cardPanel = GetComponent<UIDocument>().rootVisualElement.Q("cardpanel");
    9.             cardPanel.style.display = DisplayStyle.None;
    10.         }
    11.  
    12.         public VisualElement GetCardPanelRoot()
    13.         {
    14.             // Enable the screen with the first access to the panel, as it means we want to show cards.
    15.             ShowGameScreen();
    16.  
    17.             return cardPanel;
    18.         }
    19.  
    20.         public void HideGameScreen()
    21.         {
    22.             cardPanel.style.display = DisplayStyle.None;
    23.         }
    24.  
    25.         private void ShowGameScreen()
    26.         {
    27.             cardPanel.style.display = DisplayStyle.Flex;
    28.         }
    29.     }
    And so I think that the rootVisualElement should be available, but for some reason isn't. The UIToolkitUnityRoyaleRuntimeDemo is using the package version, where my project is using the built in version. Is this something that has broken or is this not the intended way to interact with UIDocuments?

    Anybody else having issues with this? I can put a workaround in to check if the rootVisualElement has been loaded in the Update, but this seems like a massive cludge.
     
    Last edited: Mar 17, 2021
  2. SteveSync

    SteveSync

    Joined:
    Sep 25, 2013
    Posts:
    27
    Ah, this looks like it might be an issue with enter play mode settings. When disabling that the rootVisualElement is populated as expected.

    Edit: Although not always :|

    Edit2: It fails in the built game too, so changing the play mode settings isn't the solution.
     
    Last edited: Mar 3, 2021
    Rezonanz likes this.
  3. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    696
    Hello, can you clarify the version you're using? Because Unity 2021.1 does not have built in Runtime code from UI Toolkit, only 2021.2. For Unity 2020.2 and 2021.1 you'll still need the package for Runtime UI Toolkit.
     
  4. Frog556fb2

    Frog556fb2

    Joined:
    Apr 27, 2019
    Posts:
    14
    Same in 2021.2.0a8
     
  5. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    696
    If you're both using 2021.2, we are aware of the problem and in the process of getting it fixed. It's related to execution order, since this code moved from the package to being part of Unity itself.
     
    Rezonanz likes this.
  6. SteveSync

    SteveSync

    Joined:
    Sep 25, 2013
    Posts:
    27
    Ah yes, it may have been 2021.2.0a6. Apologies for the confusion. I think I had two projects open with different versions and wrote down the wrong one :|

    You're a star! Thanks :)
     
  7. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    696
    Thanks for confirming! And apologies for the misbehavior now, we hope to get a fix for this very soon but for now unfortunately it'll be unstable and if you wish to continue using it I suggest adding some checks/delayed initialization. But I can confirm that the expected behavior is for the rootVisualElement on UIDocument instances to be not null by the time OnEnable runs on your code.

    Cheers! :cool:
     
    Frog556fb2 likes this.
  8. Slandercakes

    Slandercakes

    Joined:
    Jul 30, 2015
    Posts:
    15
    Has a fix for this been implemented yet? I'm experiencing the same issue on 2021.2.0b12.
     
  9. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    696
    The fix has been published for a while. Any chance you're trying to access the root visual element from a MonoBehaviour that uses either [ExecuteInEditMode] or [ExecuteAlways]? Because there are cases when you have just pressed the Play button when you have one of those attributes that you get to kind of a transition state and values can be unexpected.
     
  10. niel-archer

    niel-archer

    Joined:
    Nov 29, 2016
    Posts:
    17
    I'm seeing this over the weekend, tried upgrading to 2021.2.0b15 (from 0b14) but did not help.
    As for "[ExecuteInEditMode] or [ExecuteAlways]" I do not know what they are, so unlikely I set them.

    A few days ago the code was working fine, so I have no idea what has happened.
     
  11. BourbonBristles

    BourbonBristles

    Joined:
    Jan 23, 2014
    Posts:
    7
    Seeing the same issue in 2021.2.4f1, sometimes it's available, sometimes it isn't. Haven't been able to find a pattern yet.
     
  12. Ronsu900

    Ronsu900

    Joined:
    Mar 15, 2015
    Posts:
    8
    Similar in 2021.3.1f1. But in my case, rootVisualElement returns null when the UIDocument component is Disable or the GameObject is inactive.

    This is a really simple cause, so I'm not sure if it has anything to do with the case in this thread. or maybe it's just the expected behavior (but I didn't see any mention of this in the scripting API manual or google search).

    Code (CSharp):
    1. public class RootVisualElementTest : MonoBehaviour
    2. {
    3.     public GameObject uiDocumentGo;
    4.     void Start()
    5.     {
    6.         uiDocumentGo.SetActive(false);
    7.         Debug.Log(uiDocumentGo.GetComponent<UIDocument>().rootVisualElement); // Null
    8.         uiDocumentGo.SetActive(true);
    9.         Debug.Log(uiDocumentGo.GetComponent<UIDocument>().rootVisualElement);
    10.         uiDocumentGo.GetComponent<UIDocument>().enabled = false;
    11.         Debug.Log(uiDocumentGo.GetComponent<UIDocument>().rootVisualElement); // Null
    12.         uiDocumentGo.GetComponent<UIDocument>().enabled = true;
    13.         Debug.Log(uiDocumentGo.GetComponent<UIDocument>().rootVisualElement);
    14.     }
    15. }
     
    Last edited: May 3, 2022
  13. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    696
    It is expected that the root visual element is null when the component or game object are disabled. There's no UI showing, the UI doesn't exist. Is there some particular use case you're trying to accomplish that we failed to support? If so, I suggest you start a new thread describing your needs so we can talk about it :)
     
    JohnnyGo-Time likes this.
  14. Ronsu900

    Ronsu900

    Joined:
    Mar 15, 2015
    Posts:
    8
    Ok, I guess I replied out of place:oops:
    I was so used to the traditional component-based behavior that I just thought that something might be wrong with visualElement returning null and that it might be something I should share.
    If that is the default behavior then there is no problem for me that I can't accomplish.

    Thanks!
     
    JuliaP_Unity likes this.