Search Unity

UIElements questions and feedback

Discussion in 'UIElements' started by Sangemdoko, Apr 3, 2019.

  1. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hello,

    I've been testing the UIElements for two days, and with the lack of examples I'm kind of stuck in doing the things I want. I was hoping someone could push me in the right direction.

    First of all I have one weird behavior.
    <engine:Template> and <engine:Instance> in my uxml file are underlined in green and when I hover them with my mouse it says that it does not exist.

    upload_2019-4-3_16-9-57.png

    Even though it says that the Template class does not exist in the namespace, it does work fine.

    Now I have a few questions about the binding of PropertyFields.

    I want to achieve 2 complicated things.

    1. Make a rearrangeable List. Similar to how UnityEvents inspector with the +/- buttons to add/remove elements, with the addition of a drag focusable to reorder the elements.

    2. When I select one of the elements I want to draw its corresponding data below the list. The data is a bit special since the Type of data will change. The type can be any subclass of my base class "Item".
      I have three ways I could do this:
    • I can have a choice of the Type of data I want to serialize when I press the + button
    • I can have a dropDown with the Types of the data I want to serialize
    • I can have an ObjectField which takes a ScriptableObject that contains some other data, including the Type of the data I want to serialize.

      Once I know the type I want to serialize, I need to create a new SerializedProperty of that type. The problem is that Item does not inherit UnityEngine.Object. So I cannot do a new SerializedObject(my_itemWithCustomType);

      I can do my own serialization if necessary but then how would I bind my item with the UI? PropertyField can only bind to SerializedProperty or SerializedObject, so I would need to create that from any subclass of Item.
    Please do let me know if you have any advice on how I could do this.
    Thank you
     
  2. etienne_phil_unity

    etienne_phil_unity

    Unity Technologies

    Joined:
    Jan 15, 2019
    Posts:
    15
    Hello,
    Regarding the UXML file, the generated one is quite complex but it's possible to simply go with something like
    Code (CSharp):
    1. <UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
    2.     ...
    3. </UXML>
    you can take a look at [Window > UI > UIElements Samples]

    Regarding the list, we unfortunately do not support the functionality you're after at the moment,
    you likely need to write your own ReorderableList (or else) widget

    Regarding serialization,
    assuming your base class shouldn't inherit from UnityEngine.Object,
    then doing your own serialization makes sense,
    to synchronize your data on the UI,
    you can use register callbacks on ChangeEvents, such as:
    Code (CSharp):
    1. myWidget.RegisterCallback<ChangeEvent<string>>(myHandler);
    Under the hood, PropertyField relies on ChangeEvent
     
  3. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hello thank you for the reply!

    I understand that I'll have to make my own Reorderable list. I'll see if I can make a generic widget that I could reuse easily.
    And thank you for clarifying how the property field works.

    The classes should not inherit UnityEngine.Object.
    I am slightly concerned about the UI for my own serialization.
    The point is to draw 2-3 custom properties of the base class. but then I want to draw the rest of the properties, including the subclasses properties (which might be written by someone else) without having to change any of the editor/inspector code.

    The default inspector works fine for objects (non-UnityEgine.Object). So I was maybe thinking of using the DrawPropertiesExcluding function but that function uses the current object, I want to draw the properties of an attribute of the current object (like a nested inspector maybe?).

    What do you think is the best way to approach this? Is there a better way of doing this only using UIelements and not IMGUI?

    Thank you for your time
     
  4. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Also I have another question about UIElements.

    I'm trying to make a dropdown menu using the toolbarmenu type. But I'm not usre how I am suppose to add items in the dropdown. The DropDownMenu attribute "menu" is get only so I cannot assign it.

    I also tried adding visual elements inside the ToolbarMenu but that did not do what I hoped for.

    Is it a bug that "menu" is get only? Or maybe I'm trying this the wrong way. Would you be so kind as to show me an example of how it should be used.

    I aslo have issues with ListView. There I can add items (at least I think I can there are no errors). But I cannot visualize anything. For example I am trying to make a list of textElements. But nothing gets added in the editor window. I am adding the content in the itemsSource.

    I expect that once 2019.1 is fully released there will be more examples and tutorials on UIElements. But I just want to get a head start.

    Thank you for your time
     
    Last edited: Apr 9, 2019
  5. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    598
    I also have some questions about UI Elements:

    When will the earliest runtime UI Elements be available?
    At work, we're evaluating when to update our Unity version, and several UX/UI designers are interested in when the runtime UI Elements will be available, so they can start playing with it. I assume that it will be after or around the same time visual editing tools become available, based on the roadmap video. But there doesn't seem to be an exact timeframe for runtime UI Elements.

    This dovetails into my second question:

    HTML5/CSS -> UXML/USS conversion Pipeline
    As an engineer that works with a lot of UX / Design folks that have backgrounds in web-based design tools. I know a lot of the newer toolkits since Scaleform focus on HTML5-based solutions (Coherent springs to mind).

    UI Elements seems like the perfect fit to have a more "cleanly" integrated pipeline that fits with what a lot of UI folks are already familiar with, but obviously doesn't support a lot of common HTML5 presentation bits and bobs. Will there be a conversion pipeline or Unity-curated versions of common HTML concepts? If so, what's the roadmap to achieve this or should I look into rolling such a solution myself? In a perfect world, they could export HTML5/css from UXPin or other tools, run it through an importer, and anything that's compatible would get converted or work as-is.

    Tweening / animation library:
    I know there was some discussion on this, but are there any more concrete plans?

    Render <Image> with Materials
    Will there be a way to render Images and other elements with material or shader overrides for effects?
     
    EricLampi likes this.
  6. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    102
    Can you share some snippets / code around what you're trying to achieve ? Overall when it comes to SerializedProperty there should not be much different in terms of default inspector between UIElements and IMGUI. What we do not support yet are customer drawers based on the presence of an attribute which is something we will add in a future release.
     
  7. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    102
    On that specific topic, I am unsure that is needed in your case but it is possible to implement a custom binding system if you have a custom serialization. Essentially this gives you the ability to access the "bindingPath" property and implement hooks into the update the loop of the UI system for when to detect changes. That being said it is a pretty involved task and most users should not have to do that.

    Hopefully we can help you to what you need to do. Maybe if you're already very familiar with IMGUI we could help you port the same implementation to UIElements instead.
     
  8. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    102
    You can use the ToolbarMenu.menu object directly for example by calling the AppendAction() method. See this API doc page.

    We do lack a good example of the ListView, I've taken some time to write a simple script that shows a very basic usage:
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3.  
    4. using UnityEditor;
    5. using UnityEngine;
    6. using UnityEngine.UIElements;
    7.  
    8. namespace UIElementsExamples
    9. {
    10.     public class ListViewExampleWindow : EditorWindow
    11.     {
    12.         [MenuItem("Window/ListViewExampleWindow")]
    13.         public static void OpenDemoManual()
    14.         {
    15.             GetWindow<ListViewExampleWindow>().Show();
    16.         }
    17.  
    18.         public class Item
    19.         {
    20.             public readonly int index;
    21.  
    22.             public Item(int index)
    23.             {
    24.                 this.index = index;
    25.             }
    26.  
    27.             public override string ToString()
    28.             {
    29.                 return "index: " + index;
    30.             }
    31.         }
    32.  
    33.         public void OnEnable()
    34.         {
    35.             const int itemCount = 1000;
    36.  
    37.             var items = new List<Item>(itemCount);
    38.  
    39.             for (int i = 0; i < itemCount; i++)
    40.                 items.Add(new Item(i));
    41.  
    42.             Func<VisualElement> makeItem = () => new Label();
    43.  
    44.             Action<VisualElement, int> bindItem = (e, i) => (e as Label).text = items[i].index.ToString();
    45.  
    46.             var listView = new ListView(items, 30, makeItem, bindItem);
    47.  
    48.             listView.selectionType = SelectionType.Multiple;
    49.  
    50.             listView.onItemChosen += obj => Debug.Log(obj);
    51.             listView.onSelectionChanged += objects => Debug.Log(objects);
    52.  
    53.             listView.style.height = 200;
    54.  
    55.             rootVisualElement.Add(listView);
    56.         }
    57.     }
    58. }
    As a side note it would be awesome to start separate threads for the different questions as it becomes hard to track down each separate discussion. Thank you for your collaboration!
     
  9. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    102
    We are working right now to offer a preview version of UIElements in the Runtime in 2019.3. The core API will be stable while we are working on scene integration and authoring workflows inside a package that we aim to distribute as a preview package (meaning it's not recommended for use in production).

    The goal is to officially release for the Runtime in 2020 cycle, possibly as early as 2020.1 but of course this is depending on the feedback we gather and other uncertainties. Overall we aim at the 2020 LTS version to be the target for an in-game ready UIElements.

    This is not something we plan to work on anytime soon given that the subset of CSS supported is still pretty limited and also because UXML isn't exactly on par with HTML either.

    In terms of integrating with existing design tools though, this is definitely something we have in mind although right now our priority is to offer a native visual authoring experience of UXML/USS. Internally we've prototyped a Sketch plugin which shown potentially for quick bootstrapping. Generally we feel it would be very accessible for the community to publish this kind of plugin given the well defined nature of our text formats.

    Yes ! 2019.3 alpha will contain an experimental tweening animation API.

    Yes this is definitely in the plans! This is unlikely to be exposed in the 2019.3 preview because we do want to complete other rendering related functionality before giving you a shader that can be built upon / customized. But this is something we feel is strictly required for the release.
     
  10. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hi @antoine-unity

    Sorry for the late reply for some reason I did not receive a notification from your replies.

    Thanks to you I was able to add a list and a dropdown menu in my editor window.

    In terms of my special case, I'll try to explain in detail what I am trying to achieve with an example.

    Code (CSharp):
    1. class MyScriptableClass: ScriptableObject
    2.     {
    3.         [SerializeField]
    4.         protected MyClass m_myClass; //This could be removed
    5.         public int attribute;
    6.  
    7.         public virtual MyClass MyClass { get { return m_myClass; } } //if m_myClass was removed I would return null here
    8.     }
    9.  
    10.     [System.Serializable]
    11.     class MyClass
    12.     {
    13.         public MyScriptableClass myScriptableClass;
    14.         public int attribute;
    15.     }
    16.  
    17.     class MyScriptableSubClass1 : MyScriptableClass
    18.     {
    19.         [SerializeField] MySubClass1 m_mySubClass; //default values for this class
    20.         public bool attribute1;
    21.  
    22.         public override MyClass MyClass { get { return m_mySubClass; } }
    23.     }
    24.  
    25.     [System.Serializable]
    26.     class MySubClass1 : MyClass
    27.     {
    28.         public string attribute1;
    29.     }
    30.  
    31.     class MyScriptableSubClass2 : MyScriptableClass
    32.     {
    33.         [SerializeField] MySubClass2 m_mySubClass; //default values for this class
    34.         public int attribute2;
    35.  
    36.         public override MyClass MyClass { get { return m_mySubClass; } }
    37.     }
    38.  
    39.     [System.Serializable]
    40.     class MySubClass2 : MyClass
    41.     {
    42.         public float attribute2;
    43.     }
    44.  
    45.     [System.Serializable]
    46.     class MyClassList
    47.     {
    48.         public MyClass[] myClasses;
    49.     }
    50.  
    Essentially I would like to draw "MyClassList" with a custom drawer. The goal is that you would add an element in the array of "MyClass" drag and drop a scriptableObject asset which would be either "MyScriptableSubClass" 1 or 2. And the matching "MyClass" 1 or 2 would be serialized as an element of the "MyClass" array.

    So if I drop a "MyScriptableSubClass1" asset I would be able to set a string for "attribute1" of "MyClass1". The "myScriptableClass" attribute of "MyClass1" (inherited by "MyClass") would automatically be set with the dropped scriptable asset.

    You said that custom drawers are coming later. So until they arrive I will use a reusable static function to draw the MyClassList in custom inspectors. I did find this thread: https://forum.unity.com/threads/property-drawers.595369/
    which seems to show how to use propertydrawers with UIElements but there seem to be some quirks.

    Do you have any suggestions on how I could achieve my goal?

    What I had in mind was having an event triggered when the MyScriptableClass changes. I would call the MyClass getter and get the Type with GetType(). at that point, I would know if it's a "MySubClass" 1 or 2 and I would draw the relevant properties. Note that I do NOT want to change the values inside the scriptable Object. The MyClass1 attribute inside the MyScriptableSubClass1 is unrelated to the MyClass1 that I am serializing in MyClassList. It contains default values for that class In the case someone wants it.

    I do not want to write a custom drawer for each MyClass subclasses it should just use the default drawer.

    Thank you for your time, I greatly appreciate the help.
     
  11. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    Just to clarify, custom property drawers are supported in UIElements in 2019.1. What is not yet supported is Attributes on top of fields that can force the use of a custom property drawer just for that field, in that class. For example, making one of your integer fields a slider instead of an IntField.

    If you define custom property drawers for your sub classes, and not the base class, you should see the elements in the list that of the proper type use the proper custom drawer.
     
  12. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    524
    @uDamian Is there an official forum thread for UIElements feedback?

    I'd like to create a draggable element, but I can't find any examples of this. I've looked at the ShaderGraph source, but it's a complex beast. So far I understand that I need to register callbacks to MouseDownEvent and MouseUpEvent, and use element.CaptureMouse(). But how to I access the mouse position and write it to the element?

    EDIT: Also, every time I edit my stylesheet I get an error that it's missing. Is this a typical beginners fail?

    MissingReferenceException: The object of type 'StyleSheet' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Object.get_name () (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/UnityEngineObject.bindings.cs:189)
    UnityEngine.UIElements.StyleSheets.StyleSheetCache.GetPropertyID (UnityEngine.UIElements.StyleSheet sheet, UnityEngine.UIElements.StyleRule rule, System.Int32 index) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/StyleSheets/StyleSheetCache.cs:333)
    UnityEngine.UIElements.StyleSheets.StyleSheetCache.GetPropertyIDs (UnityEngine.UIElements.StyleSheet sheet, System.Int32 ruleIndex) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/StyleSheets/StyleSheetCache.cs:253)
    UnityEngine.UIElements.VisualTreeStyleUpdaterTraversal.ProcessMatchedRules (UnityEngine.UIElements.VisualElement element, System.Collections.Generic.List`1[T] matchingSelectors) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/VisualTreeStyleUpdater.cs:313)
    UnityEngine.UIElements.VisualTreeStyleUpdaterTraversal.TraverseRecursive (UnityEngine.UIElements.VisualElement element, System.Int32 depth) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/VisualTreeStyleUpdater.cs:248)
    UnityEngine.UIElements.StyleSheets.HierarchyTraversal.Traverse (UnityEngine.UIElements.VisualElement element) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/HierarchyTraversal.cs:11)
    UnityEngine.UIElements.VisualTreeStyleUpdater.ApplyStyles () (at /Users/builduser/buildslave/unity/build/Modules/UIElements/VisualTreeStyleUpdater.cs:123)
    UnityEngine.UIElements.VisualTreeStyleUpdater.Update () (at /Users/builduser/buildslave/unity/build/Modules/UIElements/VisualTreeStyleUpdater.cs:106)
    UnityEngine.UIElements.VisualTreeUpdater.UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase phase) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/VisualTreeUpdater.cs:80)
    UnityEngine.UIElements.Panel.ValidateLayout () (at /Users/builduser/buildslave/unity/build/Modules/UIElements/Panel.cs:547)
    UnityEngine.UIElements.UIElementsUtility.DoDispatch (UnityEngine.UIElements.BaseVisualElementPanel panel) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:250)
    UnityEngine.UIElements.UIElementsUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at /Users/builduser/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:78)
    UnityEngine.GUIUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at /Users/builduser/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:179)
     
    Last edited: Apr 25, 2019
  13. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    @cecarlsen
    [Please don't post unrelated questions in a thread. Start a new thread for each topic. Also, please do not double post - I see you also started a new thread with the same questions]

    For the time being, this is the forum for UIElements feedback.

    This part of the Unite LA demo shows how to do a draggable element:

    Sample code here:
    https://github.com/Unity-Technologi...b/master/Assets/Demo/Editor/TextureDragger.cs

    And the error you see tends to happen when you both edit C# (causing a domain reload) and you change a USS file. It's a known bug. For now, try to only edit one at a time.
     
    cecarlsen likes this.
  14. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hi,
    I was struggling to get the listView to work for a while and turns out it wasn't showing up because the style height was 0 ... I think the default height value shouldn't be 0 it should be at least some multiple of the height of the element.

    So that when I write:
    Code (CSharp):
    1. var list = new ListView(new string[] { "1", "2" }, 30, () => new Label(), (e, i) => (e as Label).text = i.ToString());
    2. root.add(list);
    I would want something showing in the editor window. I think having a default height of 5 to 10 times the element's height would be great. That's just my opinion though, I just think it would reduce the amount of frustration trying to figure out if your list is badly initialized or if it is null or empty, etc...

    Let me know what you think
     
  15. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hi,

    I've been testing out a few things with lists and custom property drawers. But I can't seem to get what I want and cannot figure out why?

    All I am trying to do is have a listView of Labels (names) and once an element is selected I want to draw a custom property drawer of the element I have selected.

    So assuming I have:

    Code (CSharp):
    1.  
    2. [System.Serializable]
    3.     public class Item
    4.     {
    5.         public string m_name;
    6.         public int m_interger;
    7.     }
    8.  
    9.     [System.Serializable]
    10.     public struct ItemListWrapper
    11.     {
    12.         public Item[] m_itemList;
    13.         public Item m_item;
    14.     }
    15.  
    and in the editor I have:

    Code (CSharp):
    1.  
    2. [CustomPropertyDrawer(typeof(Item))]
    3.         public class ItemPropertyDrawer : PropertyDrawer
    4.         {
    5.             public override VisualElement CreatePropertyGUI(SerializedProperty property)
    6.             {
    7.                 var container = new VisualElement();
    8.                 container.Add(new PropertyField(property.FindPropertyRelative("m_name")));
    9.                 container.Add(new PropertyField(property.FindPropertyRelative("m_interger")));
    10.                 return container;
    11.             }
    12.         }
    13.  
    14.         [CustomPropertyDrawer(typeof(ItemListWrapper))]
    15.         public class ItemListWrapperPropertyDrawer : PropertyDrawer
    16.         {
    17.             public override VisualElement CreatePropertyGUI(SerializedProperty property)
    18.             {
    19.                 var container = new VisualElement();
    20.                 var selectedObject = new VisualElement();
    21.  
    22.                 var itemPropertyField = new PropertyField(property.FindPropertyRelative("m_item"));
    23.                 container.Add(new Label("Item:"));
    24.                 container.Add(itemPropertyField);//If this is commented out the prepertyField is not drawn when object is selected
    25.  
    26.                 List<PropertyField> elements = new List<PropertyField>();
    27.                 var arrayTest = property.FindPropertyRelative("m_itemList");
    28.                
    29.                 for (int x = 0; x < arrayTest.arraySize; x++) {
    30.                     PropertyField elementproperty = new PropertyField(arrayTest.GetArrayElementAtIndex(x)); // get array element at x
    31.                     elements.Add(elementproperty);
    32.                 }
    33.  
    34.                 var arrayTest2 = (UIElementsDrawerType[])GetTargetObjectOfProperty(property.FindPropertyRelative("m_testArrayWrapper"));
    35.  
    36.                 var list1 = new ListView(elements, 20, () => new Label(), (e, i) => (e as Label).text = i.ToString());
    37.                 list1.style.height = 100;
    38.                 list1.selectionType = SelectionType.Single;
    39.                 list1.onSelectionChanged += objects =>
    40.                 {
    41.                     if (objects.Count != 0) {
    42.                         selectedObject.Clear();
    43.                         selectedObject.Add(new Label("selected")); //Gets drawn normally
    44.  
    45.                         //For ItemList
    46.                         selectedObject.Add((PropertyField)objects[0]);//Nothing
    47.                         selectedObject.Add(new PropertyField(arrayTest.GetArrayElementAtIndex(0)));//Nothing
    48.                         selectedObject.Add(elements[0]);//Nothing
    49.  
    50.                         //For Item
    51.                         selectedObject.Add(new PropertyField(property.FindPropertyRelative("m_item")));//Nothing
    52.                         selectedObject.Add(itemPropertyField);//Only gets drawn if the serialized object was already drawn before
    53.  
    54.                     }
    55.                 };
    56.                 container.Add(new Label("Item list:"));
    57.                 container.Add(list1);
    58.                 container.Add(selectedObject);
    59.  
    60.                 return container;
    61.             }
    62.         }
    63.  
    64.  
    Here is the result before I select an element in the list:
    upload_2019-5-1_15-14-4.png

    Here is the result after I select an element in the list:
    upload_2019-5-1_15-14-20.png


    Note that the selected element does not appear at all.
    The reason I added the Item ("Not in the list") is to show you that drawing a propertyField during an event, Without drawing it first, won't get drawn at all, but it will be drawn again if it was previously drawn. This is what I assume is happening for the elements in the list/array. They need to be drawn for the first time when the element is selected. But for some reason that does not work.

    Please let me know what I am doing wrong or if it a bug and it shouldn't be this way.

    Thank you
     
  16. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    ListView is a virtualized container. This means that it only creates the number of VisualElements that you can physically see, given it's size. Just like ScrollView, the idea is that you have a limited (bound) space that you want to use to show a lot more content than can fit. This means that ListView cannot have a "default size" based on its contents. It needs to be given a size by the user. If it had a default size, it would always be wrong in some cases, especially since the number of data items can change at any time.
     
  17. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    PropertyField needs to be bound to some data (a SerializedProperty) before it displays any UI. It generates different types of UI fields (as children) depending on the data type of the bound property. Integers get IntegerFields, Vector3s get Vector3Fields, etc.

    The InspectorWindow will call Bind() (which is recursive) on your custom Inspector/Editor once, when it is first displayed. Any additional elements you add to your inspector after this initial Bind() will not be bound automatically. For new PropertyFields, this means that you won't see anything. You need to manually call:
    Code (CSharp):
    1. myNewPropertyField.Bind(serializedObject);
    where `serializedObject` is already a member of `PropertyDrawer` and points to the `SerializedObject` currently being inspected.
     
  18. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Thank you @uDamian It works now.
    I make a list of serializedProperties and use that list to populate the listView. Then I can display the selected serialized property like so.
    Code (CSharp):
    1. var serializedProperty = (SerializedProperty)objects[0];
    2. var propertyField = new PropertyField(serializedProperty);
    3. propertyField.Bind(property.serializedObject);
    4. selectedObject.Add(propertyField);
    I'd like to populate the listView with labels which I would create from the data inside each element (for example the name and an integer amount). Hopefully, that's not too complicated. Then I'll figure out a way to add/remove/duplicate elements.

    If I end up being stuck for too long I'll ask for some more help.

    Thank you
     
  19. TDCreationStudios

    TDCreationStudios

    Joined:
    May 16, 2018
    Posts:
    18
    Just wondering - I was under the impression all new unity api's are going to be using proper, PascalCase for the naming convention, seems like you aren't here - I assume this will be changed on release?
     
  20. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    UIElements has already released as part of 2019.1. We aim to have a stable API going forward with minimal breaking changes. :)
     
  21. TDCreationStudios

    TDCreationStudios

    Joined:
    May 16, 2018
    Posts:
    18
    @uDamian so from what I understand - you won't be fixing the naming convention violations?

    -edit: this is a shame, I'll be honest. I was under the impression that Unity would be using the most commonly used naming convention for C# going forward, it would be really nice to have a single unified convention between my API's and Unity's own.

    -double edit: this is what I reference when I say "I was under the impression...": https://forum.unity.com/threads/concerning-direction-of-c-naming-convention-in-unity.534390/

    -third and final: seem to have found another unity team member saying that moving forward, you'll be using the MS standard conventions, so I'm just rather confused on why this isn't the case here: https://forum.unity.com/threads/naming-convention-inconsistencies.525030/
     
    Last edited: May 10, 2019
  22. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    In the threads you linked, the comments made by Unity staff indicate that there would be exceptions, namely:

    It's intentional. All the old code (in the UnityEngine and UnityEditor namespaces) will continue to use the old style, and all the new code (in the Unity namespace) will use the new style.


    UIElements is inside these namespaces. It was also long in development before the Microsoft convention adoption was made and it would be highly disruptive, if not impossible, to change it at this time.
     
  23. TDCreationStudios

    TDCreationStudios

    Joined:
    May 16, 2018
    Posts:
    18
    Interesting. That's a shame, I'll be honest, but I understand - I assume I can just modify the package contents myself to change the naming conventions? Thanks for the insights, I thought UIElements was very new.
     
  24. ChaosMage

    ChaosMage

    Joined:
    Sep 5, 2012
    Posts:
    14
    Is there any way to set ObjectField target type in uxml (scene or texture2d, for example)?
     
  25. Amitloaf

    Amitloaf

    Joined:
    Jan 30, 2012
    Posts:
    85
    Yeah I also have Derkon's problem. I make an ObjectFierd in Uxml but even if I bind to SerializedProperty, it's not able to deduce the type on his own and I need to query to set it.
     
  26. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hi I was wondering if percentage inputs for width, height, etc... will be a thing some day?

    I am trying to make a visual element that is inside a container, which would look like this:

    --- ---------
    | 1 | 3 |
    --- ---------

    1 (1/4th) and 3 (3/4th) should take all available space both horizontally and vertically.

    I was only able to either stretch the blocks horizontally or vertically, not both. I do it using flex-grow. In CSS I could be using "height: 100%" to fix this problem, but here it is not an option.

    I can't use absolute position because the visual element is inside a container that could move up and down the window.

    Any ideas how I could do this? Is it a good idea to use two containers one to stretch horizontally and another to stretch vertically?
     
  27. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    61
    Hi Sangemdoko,

    I can confirm that percentage unit will be available for the 2019.3 release.

    However, what you're trying to achieve is totally possible by only using flex.

    To do this:
    - Set the container "flex-direction: row"
    - Set element 1 "flex: 1"
    - Set element 3 "flex: 3"

    Here's a jsfiddle for reference : https://jsfiddle.net/47hnm19q/
     
  28. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Thank you @jonathanma_unity

    I found that my problem was that the parents of the visual were not set to flex-grow. So the element was indeed taking the full height of the parent, but the parent was not taking the full height of the window.

    This is unrelated but is a ReorderableList equivalent for UIElements planned for the near future?

    Also is there anything in place to have conditions when changing values on a propertyField?
    Example checking that the scriptableObject that is being added to an ObjectField has a certain attribute value before it is actually added to the serializedObject.
     
  29. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    61
    ReorderableList is not something that is planned for this year.

    Sadly there isn't any mechanism in place to validate values assigned to a PropertyField.
     
  30. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Thank you @jonathanma_unity

    I guess I'll try to make my own ReordarableList.
    I'll also try to make my own "DelayedTextField" element. For that I need to check when the textfield loses focus or if the enter key is pressed. I guess I can use the FocusController and FocusOutEvent. But I'm not quite sure about the enter key. Am I correct in assuming that I should use the InputEvent or KeyDownEvent?

    Thank you, I really appreciate the advice.
     
  31. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    61
    Delayed TextField is something that is already available in UIElements, so you shouldn't have to implement it.
    To enable it set the "isDelayed" property on the TextField to true.
     
  32. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Hi @jonathanma_unity,

    I didn't realise that isDelayed was a thing, thank you for bringing it up.

    I advanced a bit with my ReordarableList component and it is kind of working with some weird visual bugs that I'll try to work out.
    One of the things I require is to open the ObjectSelector window to select the scriptableObject asset to add in my list.

    From what I understand I cannot use "EditorGUIUtility.ShowObjectPicker" because it only works in OnGUI. I still tried but the window does not show, and there is no way for me to add an action to the closing event.

    So I looked at how it was done in the "ObjectField" VisualElement. There they use
    "ObjectSelector.get.Show"

    I can't use ObjectSelector because it is an "internal" class.

    How would you suggest I open the ObjectPicker for a certain type and get the selected object when the ObjectPicker window is closed?

    My current workaround would be to open a custom popup window with an ObjectField inside, which adds a intermediary window that should not have exist.
     
  33. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    Actually I found another work around. I use the IMGUIContainer to check for the close event.
    Code (CSharp):
    1.  objectPickerContainer.onGUIHandler = () =>
    2.                 {
    3.                     var selectedObject = EditorGUIUtility.GetObjectPickerObject();
    4.  
    5.                     if (Event.current.commandName == "ObjectSelectorClosed")
    6.                     {
    7.                         //do something here
    8.  
    9.                         objectPickerContainer.onGUIHandler = () => { };
    10.                     }
    11.  
    12.                 };
     
  34. jonathanma_unity

    jonathanma_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    61
    Have you tried calling "EditorGUIUtility.ShowObjectPicker"?
    I took a quick look and I don't see anything preventing you from calling it...
     
  35. jleybovich_unity

    jleybovich_unity

    Joined:
    Oct 26, 2018
    Posts:
    4
    I like where the new system is heading. I do have a question, is there a way to tell that the UI Elements have changed? i.e. An equivalent to EditorGUI.EndChangeCheck? Or a way to tell if the data is "dirty"?
     
  36. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    43
    UIElements uses events instead of polling to get changes notification. If you use a field that implements INotifyValueChanged, you can use myField.RegisterValueChangedCallback(ChangeEvent<T>) to be notified when a new value has been entered.
     
  37. jleybovich_unity

    jleybovich_unity

    Joined:
    Oct 26, 2018
    Posts:
    4
    1. Thanks @UnityMat, I am trying what you suggested but am still running into some issues. I cannot seem to add and remove VisualElements dynamically. I have a dynamic PropertyDrawer that displays different properties based on an EnumField. I am able to get the changed callback but when I try to add and remove PropertyFields based on the changing enum I do not see the other properties. I tried SetEnabled, visible and adding/removing from the parent container but none of these methods work as needed for the intended use-case.

    2. On a related note, is there a way to cause a rebuild of the UI and when would that be appropriate to call?

    3. Also Is there a way to detect ANY change within a VisualElement or its children? I would like to detect any change to any PropertyFields and apply the changes to the MonoBehaviour and other associated objects. Or is the only alternative to register to EditorApplication.Update?

    4. When using Foldouts, is there a way to have them remember their state? Must it rely on EditorPrefs or is there a better way? Currently, if you select another object then come back to the object it defaults to open.

    Any example code would be appreciated outside of the videos already on YouTube.

    Thanks for your help
     
    Last edited: Jul 31, 2019
  38. jleybovich_unity

    jleybovich_unity

    Joined:
    Oct 26, 2018
    Posts:
    4
    @UnityMat, I was able to work past most of the issues I mentioned and found some other limitations. However Number 1 is still a bit of a blocker for me. Could you please address how we should add and remove elements dynamically? The obvious API does not seem to work as expected.

    Thanks,
     
  39. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    51
    @jleybovich_unity, What I do is create a container VisualElement for any of my dynamic elements. I simply add the container to my panel (any child of the root visual element of the window). Then I can add my dynamic element to the container any time (using Add() ). If I want to remove it I simply remove the element from the container by either clearing the container (using Clear() on the parent ) or by removing only one element (using Remove())
    You can find the VisualElement documentation here:
    https://docs.unity3d.com/ScriptReference/UIElements.VisualElement.html
    There's even an event that is called when a visualement is removed from a window. You can read about the events that are built in here:
    https://docs.unity3d.com/Manual/UIE-Events-Reference.html
    I hope this helps
     
  40. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    43
    @jleybovich_unity: Can you create a new forum post with your question and a code snippet of what you're trying to do, that would be the easiest way to help.
     
  41. jleybovich_unity

    jleybovich_unity

    Joined:
    Oct 26, 2018
    Posts:
    4
    @Sangemdoko @UnityMat thanks for the feedback. I was able to get with working with clearing the container element. I think what was messing me up was the fact that the editor scripts are shared among all instances of the property/MonoB so holding onto references of the dynamic elements was not sufficient. I was able to work around it by passing in the elements through the lambda in the ChangeValue events, seemed to be the easiest way to make the references match up with the appropriate fields. Not sure if there is a way to declare an element in the uxml that ties directly to a field. The demo project just shows a custom editor but if you look at the PropSpawner MonoB you will notice it is empty. Maybe an example that shows the full cycle would help. Thanks again for your time and patience.
     
  42. LeCj

    LeCj

    Joined:
    Dec 17, 2014
    Posts:
    1
    Hello, will decorator drawers be supported?
     
  43. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    294
    Yes. Decorators are on our short term roadmap. Hoping to having them in by 2020.1 (may come later but definitely before UIElements 1.0 is officially done).