Search Unity

Showcase [Resource] EDITOR: How to determine if an element is in the UI Builder Canvas

Discussion in 'UI Toolkit' started by _geo__, Jun 8, 2023.

  1. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,343
    I've had the need to know if an element is inside the UI BuilderCanvas or not. I needed this for some extensions of the UI Builder for an Asset I am making.

    New elements (custom controls) are instantiated and attached/detached multiple times before actually landing in the UI Builder Canvas and the GameView / UIDocument. First they appeary when hovered in a "UI.Builder.BuilderTooltipPreview", then in the UI Builder, and then finally in ther UI Builder Canvas.

    The methods are based on the internal UI Builder visual tree naming conventions.They may break in future releases. So far they worked in Unity 2021.2+, 2022 and 2023.

    Maybe there is a better method. If someone knows a proper public API for this, please let me know :)

    Code (CSharp):
    1. using UnityEngine.UIElements;
    2. namespace Kamgam
    3. {
    4.     public static class Utils
    5.     {
    6.         /// <summary>
    7.         /// Anything that has an EditorPanel as parent or is a child of a BuilderCanvas is
    8.         /// considerd to be part of the builder.
    9.         /// </summary>
    10.         /// <param name="ve"></param>
    11.         /// <returns></returns>
    12.         public static bool IsPartOfUIBuilderCanvas(VisualElement ve)
    13.         {
    14. #if UNITY_EDITOR
    15.             if (ve == null)
    16.                 return false;
    17.  
    18.             // Shortcut if not an editor panel.
    19.             if (ve.panel != null && ve.panel.contextType != ContextType.Editor)
    20.             {
    21.                 return false;
    22.             }
    23.  
    24.             bool isInBuilderCanvas = Utils.isInBuilderCanvas(ve);
    25.             return isInBuilderCanvas;
    26. #else
    27.             return false;
    28. #endif
    29.         }
    30.  
    31.         /// <summary>
    32.         /// Returns true if the element is part of an EditorPanel and if it is NOT a
    33.         /// child of "UI.Builder.BuilderCanvas".
    34.         /// </summary>
    35.         /// <param name="ve"></param>
    36.         /// <returns></returns>
    37.         public static bool IsPartOfUIBuilderButNotInTheCanvas(VisualElement ve)
    38.         {
    39. #if UNITY_EDITOR
    40.             if (ve == null)
    41.                 return false;
    42.  
    43.             // Shortcut if not an editor panel.
    44.             if (ve.panel != null && ve.panel.contextType != ContextType.Editor)
    45.             {
    46.                 return false;
    47.             }
    48.  
    49.             bool isInBuilderCanvas = Utils.isInBuilderCanvas(ve);
    50.             return !isInBuilderCanvas;
    51. #else
    52.             return false;
    53. #endif
    54.         }
    55.  
    56. #if UNITY_EDITOR
    57.         private static bool isInBuilderCanvas(VisualElement element)
    58.         {
    59.             var parent = element.parent;
    60.             while (parent != null)
    61.             {
    62.                 if (parent.GetType().FullName.Contains("UI.Builder.BuilderCanvas"))
    63.                 {
    64.                     return true;
    65.                 }
    66.                 parent = parent.parent;
    67.             }
    68.  
    69.             return false;
    70.         }
    71. #endif
    72.     }
    73.  
    74. }
     
    Last edited: Jun 8, 2023
    Hellfim likes this.