Unity 6.3
0 онлайн 42 гостей 3 в системе
Вход

Привязка настраиваемого контроля к настраиваемому типу данных

Версия: 2021.3+

В этом примере показано, как связать пользовательские элементы управления с пользовательскими типами данных.

Примерный обзор

В этом примере создается пользовательский тип данных и пользовательский контроллер, основанный на трех встроенных контроллерах. Он привязывает пользовательский контроллер к пользовательскому типу данных. Ящик преобразует между градусами Цельсия и Фаренгейта.

Скрипт с пользовательским контролем, который преобразует температуру, отображаемую в Unity Editor.
Скрипт с пользовательским контролем, который преобразует температуру, отображаемую в Unity Editor.

Вы можете найти завершенные файлы, созданные этим примером, в хранилище GitHub.

Предварительные условия

Это руководство предназначено для разработчиков, знакомых со скриптами Unity Editor, UI Toolkit и C#. Перед началом работы ознакомьтесь со следующим:

Создание пользовательского типа данных

Создайте пользовательский тип данных Temperatureи используйте его в качестве серийного свойства.

  1. Создайте проект Unity с любым шаблоном.

  2. Создайте папку с именем bind-custom-data-type для хранения всех файлов.

  3. Создайте скрипт C# с именем Temperature.cs и замените его содержимое следующим:

    using System;
    
    namespace UIToolkitExamples
    {
        public enum TemperatureUnit
        {
            Celsius,
            Farenheit
        }
    
        [Serializable]
        public struct Temperature
        {
            public double value;
            public TemperatureUnit unit;
        }
    }
    
  4. Создайте скрипт C# с именем PlanetScript.cs и замените его содержимое следующим:

    using UnityEngine;
    
    namespace UIToolkitExamples
    {
        public class PlanetScript : MonoBehaviour
        {
            public Temperature coreTemperature;
        }
    }
    

Создание настраиваемого контроля

Создайте пользовательский редактор для Planet и пользовательский ящик свойств для Temperature.

В пользовательском ящике свойств реализуйте кнопку, которая преобразует температуру между Фаренгейтом и Целзиусом путем записи в свойства SerializedProperty (используйте doubleValue и enumValueIndex) и вызова SerializedObject.ApplyModifiedProperties().

Пользовательские свойства Draweris рассматривается как пользовательский контроль. Это встроенный контроль, который ведет себя в пользовательский способ.

  1. Создайте папку под названием Editor.

  2. В течение Редактор папка, создать C# скрипт назван PlanetEditor.cs и заменить его содержание следующим:

    using UnityEditor;
    using UnityEngine.UIElements;
    using UnityEditor.UIElements;
    
    namespace UIToolkitExamples
    {
        [CustomEditor(typeof(PlanetScript))]
        public class PlanetEditor : Editor
        {
            public override VisualElement CreateInspectorGUI()
            {
                return new PropertyField(serializedObject.FindProperty("coreTemperature"));
            }
        }
    }
    
  3. В течение Редактор папка, создать C# скрипт назван TemperatureDrawer.cs и заменить его содержание следующим:

    using UnityEditor;
    using UnityEngine;
    using UnityEngine.UIElements;
    
    namespace UIToolkitExamples
    {
        [CustomPropertyDrawer(typeof(Temperature))]
        public class TemperatureDrawer : PropertyDrawer
        {
            public override VisualElement CreatePropertyGUI(SerializedProperty property)
            {
                var asset = Resources.Load<VisualTreeAsset>("temperature_drawer");
                var drawer = asset.Instantiate(property.propertyPath);
    
                drawer.Q<Label>().text = property.displayName;
    
                // Don't allow conversion when you've selected multiple objects in the Inspector
                if (!property.serializedObject.isEditingMultipleObjects)
                {
                    drawer.Q<Button>().RegisterCallback<ClickEvent, SerializedProperty>(Convert, property);
                }
    
                return drawer;
            }
    
            static void Convert(ClickEvent evt, SerializedProperty property)
            {
                var valueProperty = property.FindPropertyRelative("value");
                var unitProperty = property.FindPropertyRelative("unit");
    
                // F -> C
                if (unitProperty.enumValueIndex == (int)TemperatureUnit.Farenheit)
                {
                    valueProperty.doubleValue -= 32;
                    valueProperty.doubleValue *= 5.0d / 9.0d;
                    unitProperty.enumValueIndex = (int)TemperatureUnit.Celsius;
                }
                else // C -> F
                {
                    valueProperty.doubleValue *= 9.0d / 5.0d;
                    valueProperty.doubleValue += 32;
                    unitProperty.enumValueIndex = (int)TemperatureUnit.Farenheit;
                }
    
                // Important: Because you are bypassing the binding system, you must save the modified SerializedObject
                property.serializedObject.ApplyModifiedProperties();
            }
        }
    }
    

Установить привязку

Создайте файл UXML со следующими элементами:

  • А DoubleField
  • Ан EnumField
  • Кнопка

Установите binding-path двух полей на value и unit свойства Temperature.

  1. В течение Редактор папка, создать папку с названием Resources.

  2. В течение Ресурсы папка, создать UI Документ назван temperature_drawer.uxml и заменить его содержание следующим:

    <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
        <ui:VisualElement class="unity-base-field">
            <ui:Label class="unity-base-field__label" />
            <ui:VisualElement class="unity-base-field__input" style="flex-direction: row;">
                <uie:DoubleField binding-path="value" />
                <uie:EnumField binding-path="unit" />
                <ui:Button text="Convert" />
            </ui:VisualElement>
        </ui:VisualElement>
    </ui:UXML>
    

Проверка привязки

  1. Создайте пустой GameObject в сцене.
  2. В Hierarchy выберите GameObject.
  3. Перетащите PlanetScript.cs в Inspector. Это добавит компонент Planet Script в GameObject.
  4. Введите число в поле Температура и выберите единицу из раскрывающегося списка.
  5. Выберите кнопку Convert для преобразования между единицами. Если вы измените Inspector UI, свойство Temperature пользовательского контроля изменится.

Дополнительные ресурсы