Search Unity

UI builder and custom elements

Discussion in 'UI Toolkit' started by Hertzole, Nov 28, 2019.

  1. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    Quoting @uDamian further up:

    To finish up, just mentioning that if you're doing UI for Runtime, don't use the
    AssetDatabase
    as that's Editor only. You can either load from Resources, Addressables or have a reference to it stored somewhere like a ScriptableObject.
     
  2. herra_lehtiniemi

    herra_lehtiniemi

    Joined:
    Feb 12, 2017
    Posts:
    133
    @uDamian I'm trying to implement drag'n drop on an inherited VisualElement like in your example.

    However, for some reason, RegisterCallBack<MouseDownEvent> doesn't trigger on this custom element - the mousedown-handler only reports clicks on the child elements of this custom element but not the parent element itself. I tried adding picking-mode="Position" to UXML, but still nothing.

    When making custom elements like in your example, is there something special I need to do to make the custom element register clicks?

    My factory looks like this:

    Code (CSharp):
    1.         public new class UxmlFactory : UxmlFactory<DraggableVisualElement, UxmlTraits> { }
    2.  
    3.         public new class UxmlTraits : VisualElement.UxmlTraits
    4.         {
    5.  
    6.             public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
    7.             {
    8.                 get { yield break; }
    9.             }
    10.  
    11.             public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
    12.             {
    13.                 base.Init(ve, bag, cc);
    14.             }
    15.         }
     
    Last edited: Feb 7, 2022
  3. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    Not sure if this fixes your issue, but in general you should use PointerDownEvent instead of MouseDownEvent. It has more information in it, it's less susceptible to being prevented by another event, and it's compatible with touch and pen input, with multiple fingers or pens at the same time if needed.

    The thing to know is that many standard controls use pointer events and, when they use that pointer event, they call PreventDefault (in addition to the usual StopPropagation). That call to PreventDefault will prevent any equivalent Mouse events (MouseDownEvent in your case) from being dispatched at all, meaning that you wouldn't catch them event if you registered your callback on the parent in the TrickleDown phase.
     
  4. eddiesc

    eddiesc

    Joined:
    Oct 28, 2016
    Posts:
    5
    Hey,
    I was trying to follow the Documentation about creating custom elements: https://docs.unity3d.com/Manual/UIB-structuring-ui-custom-elements.html. It shows how to create Custom Element with String Attr and Int Attr fields in the UI Builder inspector but neither of those fields are displayed in the Preview window.

    upload_2022-8-7_11-51-8.png

    So it led me to 2 questions.

    Question 1:
    Could someone clarify why in the documentation those fields are only put in the MyElement inspector and not displayed in the preview window? Is it an example of data that can be setup in the inspector and used internally in the C# code?

    Question 2:
    How to write C# code to properly display String Attr and Int Attr fields so they show up in the preview window? I have created the code myself, but I'm not sure if it is correct way of doing it:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEditor.UIElements;
    3. using UnityEngine.UIElements;
    4.  
    5. public class MyElement : VisualElement
    6. {
    7.     public MyElement()
    8.     {
    9.         hierarchy.Add(new TextField("String Attr"));
    10.         hierarchy.Add(new IntegerField("Integer Attr"));
    11.     }
    12.  
    13.     public new class UxmlFactory : UxmlFactory<MyElement, UxmlTraits>
    14.     { }
    15.  
    16.     public new class UxmlTraits : VisualElement.UxmlTraits
    17.     {
    18.         private UxmlStringAttributeDescription m_string = new() { name = "string-attr", defaultValue = "default_value" };
    19.         private UxmlIntAttributeDescription m_int = new() { name = "int-attr", defaultValue = 2 };
    20.  
    21.         public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
    22.         {
    23.             get
    24.             {
    25.                 yield break;
    26.             }
    27.         }
    28.  
    29.         public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
    30.         {
    31.             base.Init(ve, bag, cc);
    32.  
    33.             var ate = ve as MyElement;
    34.  
    35.             ate.stringAttr = m_string.GetValueFromBag(bag, cc);
    36.             ate.intAttr = m_int.GetValueFromBag(bag, cc);
    37.  
    38.             ve.Q<TextField>().value = ate.stringAttr;
    39.             ve.Q<IntegerField>().value = ate.intAttr;
    40.         }
    41.     }
    42.  
    43.     public string stringAttr { get; set; }
    44.     public int intAttr { get; set; }
    45. }
    46.  

    And the result looks like this and the values from the MyElement inspector are correlated with preview window:

    upload_2022-8-7_11-56-31.png
     
  5. pokelocos

    pokelocos

    Joined:
    Nov 9, 2015
    Posts:
    54
    Is there a way to create a custom attribute that allows adding a texture directly like the 'image' field does in the background? Currently, I have a string field and pass the image's path, but this can cause issues if I move the image to another folder or something like that. I appreciate any kind of help.
    upload_2023-3-29_9-56-52.png
     

    Attached Files:

  6. martinpa_unity

    martinpa_unity

    Unity Technologies

    Joined:
    Oct 18, 2017
    Posts:
    480
  7. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    136
    Suppose, in the UI Builder for runtime, I want to access the image component of the background of a visual element in a custom control. What should I do? The code that I have seen thus far is for strings and floats, but I don't see how to access different components of the visual elements like background image, margins, etc. in custom controls when I use them in another UXML document.

    Thanks.
     
  8. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    You should be able to access them through the style or resolvedStyle property of the visual element.
    It will give you access to the USS properties of the element.
    https://docs.unity3d.com/ScriptReference/UIElements.IStyle.html

    https://docs.unity3d.com/ScriptReference/UIElements.IResolvedStyle.html
     
  9. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    136
  10. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    136
    Is this still a good method? I want to try it since once I set a value on a custom control attribute in the inspector, it disappears as soon as I click off of it.