Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by craftsmanbeck · May 14, 2020 at 02:37 AM · c#propertydrawereditor extensionuitoolkitpropertyfield

How does one access the Label argument of a PropertyField within a PropretyDrawer using UIToolkit/UIElements?

Title. I want to be able to create my own label for a PropertyField, but when using a custom PropertyDrawer the "label" argument of the PropertyField constructor seems to be entirely ignored. Further I can't seem to find any "label" or "text" fields or the like.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by exploringunity · May 27, 2020 at 04:03 AM

Hey @craftsmanbeck,

It does appear that the label argument to the PropertyField constructor is ignored during CreateInspectorGUI when using a custom property drawer with UIElements. However, I have found a bit of a hack workaround using EditorCoroutineUtility.StartCoroutine. You can install the EditorCoroutine package via Window -> Package Manager. Be sure to check Advanced -> Show Preview Packages.

Below is an example that demonstrates the problem of not being able to set the labels as well as a solution. It uses the Recipe/Ingredient data structure from https://docs.unity3d.com/ScriptReference/PropertyDrawer.html. Here's a screenshot of the resulting UI (note the custom labels):

final ui


Assets/Recipe.cs

 // From the example at https://docs.unity3d.com/ScriptReference/PropertyDrawer.html
 using System;
 using UnityEngine;
 
 public enum IngredientUnit { Spoon, Cup, Bowl, Piece }
 
 // Custom serializable class
 [Serializable]
 public class Ingredient
 {
     public string name;
     public int amount = 1;
     public IngredientUnit unit;
 }
 
 public class Recipe : MonoBehaviour
 {
     public Ingredient potionResult;
     public Ingredient[] potionIngredients;
 }


Assets/Editor/IngredientDrawer.cs

 using UnityEditor;
 using UnityEditor.UIElements;
 using UnityEngine.UIElements;
 
 [CustomPropertyDrawer(typeof(Ingredient))]
 public class IngredientDrawer : PropertyDrawer
 {
     public override VisualElement CreatePropertyGUI(SerializedProperty property)
     {
         // NOTE: This gets called when you call `ui.Bind()` in `RecipeEditor.cs`,
         //       but also gets called again automatically afterwards, which seems
         //       to be what's blowing away the changes to the labels.
         //Debug.Log($"[IngredientDrawer.CreatePropertyGUI] - {property.displayName}"); // For tracing
 
         var container = new VisualElement();
 
         // NOTE: These 3 `label` arguments work fine
         var amountField = new PropertyField(property.FindPropertyRelative("amount"), "Amount (arg)");
         var unitField = new PropertyField(property.FindPropertyRelative("unit"), "Unit (arg)");
         var nameField = new PropertyField(property.FindPropertyRelative("name"), "Name (arg)");
 
         container.Add(amountField);
         container.Add(unitField);
         container.Add(nameField);
 
         return container;
     }
 }


Assets/Editor/IngredientDrawer.cs

 using System.Collections;
 using Unity.EditorCoroutines.Editor;
 using UnityEditor;
 using UnityEditor.UIElements;
 using UnityEngine;
 using UnityEngine.UIElements;
 
 [CustomEditor(typeof(Recipe))]
 public class RecipeEditor : Editor
 {
     PropertyField resultField;
     PropertyField ingredientsField;
 
     public override VisualElement CreateInspectorGUI()
     {
         //Debug.Log($"[RecipeEditor.CreateInspectorGUI] - BEGIN"); // For tracing
 
         var ui = new VisualElement();
 
         // NOTE: The `label` arguments, "Result (arg)" and "Ingredients (arg)", seem to be ignored.
         //resultField = new PropertyField(serializedObject.FindProperty("potionResult"), "Result (arg)");
         //ingredientsField = new PropertyField(serializedObject.FindProperty("potionIngredients"), "Ingredients (arg)");
 
         // NOTE: Setting the `label` property after creating the fields also doesn't work.
         //resultField.label = "Result (set prop)";
         //ingredientsField.label = "Test Ingredients (set prop)";
 
         resultField = new PropertyField(serializedObject.FindProperty("potionResult"));
         ingredientsField = new PropertyField(serializedObject.FindProperty("potionIngredients"));
         ui.Add(resultField);
         ui.Add(ingredientsField);
 
         // Calling `Bind` actually fleshes out the PropertyFields above, but it doesn't matter,
         // since the fields get overwritten later, so setting the labels after this still won't work.
         ////Debug.Log(ingredientsField.childCount); // 0
         //ui.Bind(serializedObject);
         ////Debug.Log(ingredientsField.childCount); // 1 -- doesn't matter
 
 
         // HOWEVER!! Setting the labels in a coroutine later does work!!
         EditorCoroutineUtility.StartCoroutine(InitializeUICoroutine(), this);
         EditorCoroutineUtility.StartCoroutine(RefreshUICoroutine(), this);
 
         //Debug.Log($"[RecipeEditor.CreateInspectorGUI] - END"); // For tracing
 
         return ui;
     }
 
     void InitializeUI()
     {
         // Static labels (not dynamic list/array)
         // OPTION: Create and insert a new label
         resultField.Insert(0, new Label("Result (coroutine)"));
     }
 
     void RefreshUI()
     {
         //Debug.Log($"[RecipeEditor.UpdateLabels]"); // For tracing
 
         // OPTION: Find and edit an existing label
         var foldout = ingredientsField.Q<Foldout>("unity-foldout-potionIngredients");
         foldout.text = "Potion Ingredients (coroutine)";
 
         // Alternative quick-n-dirty way to do the above since we know it's the first label
         //ingredientsField.Q<Label>().text = "Potion Ingredients (coroutine2)";
 
         // Another example of finding and editing an existing label
         var sizeField = ingredientsField.Q<IntegerField>("unity-input-potionIngredients.Array.size");
         sizeField.label = "Size (coroutine)";
 
         // Really hacky way to set a label's text, if you know the exact child layout (FRAGILE!)
         //((Label)ingredientsField[0][0][0][0]).text = "Size (coroutine2)";
 
         // New size field needs a new event handler
         sizeField.RegisterCallback<BlurEvent>(HandleSizeFieldBlur);
     }
 
     IEnumerator InitializeUICoroutine()
     {
         yield return new WaitForSecondsRealtime(0.067f);
         InitializeUI();
     }
 
     IEnumerator RefreshUICoroutine()
     {
         yield return new WaitForSecondsRealtime(0.067f);
         RefreshUI();
     }
 
     void HandleSizeFieldBlur(BlurEvent evt)
     {
         EditorCoroutineUtility.StartCoroutine(RefreshUICoroutine(), this);
     }
 
 }


And here's a screenshot of when I was using the UIElements debugger to find the structure of the UI:

debugger view

Note: tested with Unity version 2019.3.13f1 and 2020.1.0b3


Hope this helps!


screenshot-3.png (175.1 kB)
screenshot-4.png (18.7 kB)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

720 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Custom attribute not respecting property's PropertyDrawer 0 Answers

Custom PropertyDrawer causes NullReferenceException 1 Answer

UI Toolkit: Is it possible to modify USS custom properties (variables) with C#? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges