Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Cannot query for an element, returns null.

Discussion in 'UI Toolkit' started by kkkkkkkkkkk0, May 3, 2022.

  1. kkkkkkkkkkk0

    kkkkkkkkkkk0

    Joined:
    Nov 23, 2021
    Posts:
    7
    I managed to use C# to create additional items and append them, but not remove them, clone them or store them. The creation and appending has succeeded, so the connection between C# script and UXML is valid (no crazy lack of references)

    Code:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UIElements;
    3.  
    4.  
    5. namespace UITEST
    6. {
    7.     public class CompProc : MonoBehaviour
    8.     {
    9.  
    10.         UIDocument doc;
    11.         VisualElement root;
    12.         VisualElement prefab;
    13.      
    14.  
    15.         void Start()
    16.         {
    17.             doc = GetComponent<UIDocument>();
    18.             root = doc.rootVisualElement;
    19.  
    20.  
    21.             // This works. So the UXML works.
    22.             var newBox = new UnityEngine.UIElements.Box();
    23.             var newLabel = new UnityEngine.UIElements.Label("Holy smokes batman!");
    24.             newBox.Add(newLabel);
    25.             root.Add(newBox);
    26.  
    27.          
    28.             // This returns null, why?
    29.             prefab = root.Q<UnityEngine.UIElements.Button>("prefab");
    30.             Debug.Log(prefab); // Null
    31.          
    32.          
    33.             // How do I clone
    34.             for (int i = 0; i < 10; i++)
    35.             {
    36.                 //root.Append("dataHolder", buttonPrefab) ??????
    37.             }
    38.  
    39.          
    40.             // How do I remove an object?
    41.             var remBtn = root.Q<UnityEngine.UIElements.Box>("remBtn");
    42.             root.Remove(remBtn);
    43.             // ArgumentException: Cannot remove null child
    44.          
    45.         }
    46.  
    47.     }
    48. }
    49.  
    And UXML:
    Code (CSharp):
    1. <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
    2.     <Style src="test.uss" />
    3.     <ui:Box class="dataHolder">
    4.         <ui:Button text="New Button" name="button" class="prefab" />
    5.         <ui:Button text="RemBtn" name="button" class="remBtn" />
    6.     </ui:Box>
    7. </ui:UXML>
    8.  
    Note: I really really don't like UI Builder and I would really really focus on the C# approach to dynamically remove/add things.
     
  2. griendeau_unity

    griendeau_unity

    Unity Technologies

    Joined:
    Aug 25, 2020
    Posts:
    230
    The first query is not working because it is searching by name and not class name.
    root.Q<Button>(className: "prefab");

    It's the same thing for the item you want to remove. You have the correct remove syntax, the Query is returning a null value though.

    To clone a VisualTree, it would look something like this. You can use either Instantiate() or CloneTree(rootElement).

    Code (CSharp):
    1. var vta = AssetDatabase.LoadMainAssetAtPath("Path/To/Asset.uxml") as VisualTreeAsset;
    2. vta.CloneTree(rootVisualElement);
    3. // Or
    4. vta.Instantiate();
    5.  
    Otherwise, if it's just a single element, like a custom button, you could implement a new class that inherits from button and which applies the correct style classes. Then it's just a matter of doing
    new CustomButton();


    Is there something in particular that you don't like about it? What do you think needs improvement?
     
    kkkkkkkkkkk0 likes this.
  3. kkkkkkkkkkk0

    kkkkkkkkkkk0

    Joined:
    Nov 23, 2021
    Posts:
    7
    I had an entire paragraph here which I deleted because it seems to have vanished. When you edit UXML script, under certain conditions, UIBuilder will popup for no reason. Closing it doesn't help, uninstalling it breaks UIToolkit. Thats my remaining issue, it has to be installed, it popups without request and cannot be removed and isn't worked in.

    Two other things which happened to me but aren't true anymore are that UIBuilder would throw an error saying "do not edit files externally, because it could cause data loss" and that you couldn't unset width of an element (to go 'width: auto') because as soon as you added another element, it would still forcibly apply a fixed size of 450px which wasn't present in code. But they are gone for now.

    Other than that props to UIToolkit developers at Unity. Making UI is finally not a burden.

    --

    The remove part threw:
    ArgumentException: This visualElement is not my child

    from code:
    Code (CSharp):
    1. var remBtn = root.Q<UnityEngine.UIElements.Button>(className: "remBtn");
    2.             Debug.Log(remBtn);
    3.             root.Remove(remBtn);
    I'll try to getting closer in hierarchy and then select the object.

    edit3:

    This works:
    Code (CSharp):
    1.  
    2.             var dataHolder = root.Q<UnityEngine.UIElements.Box>(className: "dataHolder");
    3.             var remBtn = dataHolder.Q<UnityEngine.UIElements.Button>(className: "remBtn");
    4.            
    5.             Debug.Log(remBtn);
    6.             dataHolder.Remove(remBtn);
    You actually have to go to the parent of that object.
     
    Last edited: May 4, 2022
  4. griendeau_unity

    griendeau_unity

    Unity Technologies

    Joined:
    Aug 25, 2020
    Posts:
    230
    Right, the encouraged workflow is to use the UI Builder, so opening a UXML file with a double click for example will open the builder. This could maybe be a setting like choosing your IDE in the preferences.

    Oh right, you can also call
    RemoveFromHierarchy
    on the element directly. A lot easier that way. No need to know the parent :)
     
    Snoozed and kkkkkkkkkkk0 like this.