Version: Unity 6.0 (6000.0)
言語 : 日本語
カスタムコントロールをバインドする
エディター UI のサポート

カスタムコントロールをカスタムデータ型にバインドする

バージョン: 2021.3+

この例では、カスタムコントロールをカスタムデータ型にバインドする方法を説明します。

例の概要

この例では、3 つのビルトインインコントロールに基づいて、カスタムデータ型とカスタムコントロールを作成します。また、そのカスタムコントロールとカスタムデータ型をバインドします。ドロワーで摂氏から華氏へ変換します。

この例で作成する完成したファイルは、GitHub リポジトリにあります。

必要な要件

このガイドは、Unity エディター、UI Toolkit、および C# スクリプトに精通している開発者を対象としています。始める前に、以下の点を理解しておいてください。

カスタムデータ型の作成

カスタムデータ型 Temperature を作成し、シリアル化されたプロパティとして使用します。

  1. 任意のテンプレートで Unity プロジェクトを作成します。

  2. bind-custom-data-type という名前のフォルダーを作成し、すべてのファイルをここに保存します。

  3. Temperature.cs という名の C# スクリプトを作成し、そのコンテンツを以下と置き換えます。

    using System;
    
    namespace UIToolkitExamples
    {
        public enum TemperatureUnit
        {
            Celsius,
            Farenheit
        }
    
        [Serializable]
        public struct Temperature
        {
            public double value;
            public TemperatureUnit unit;
        }
    }
    
  4. PlanetScript.cs という名の C# スクリプトを作成し、そのコンテンツを以下と置き換えます。

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

カスタムコントロールの作成

Planet 用のカスタムエディターと Temperature 用のカスタムプロパティドロワーを作成します。

カスタムプロパティドロワーで、温度を華氏から摂氏に変換するボタンを実装します。その方法として、SerializedProperty のプロパティに doubleValueenumValueIndex を使用して書き込み、SerializedObject.ApplyModifiedProperties() を呼び出します。

カスタムプロパティドロワーは、カスタムコントロールと見なされます。特別な動作をするビルトインコントロールです。

  1. Editor という名前のフォルダーを作成します。

  2. Editor フォルダーに、PlanetEditor.cs という名前の C# スクリプトを作成し、そのコンテンツを以下と置き換えます。

    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. Editor フォルダーに、TemperatureDrawer.cs という名前の C# スクリプトを作成し、そのコンテンツを以下と置き換えます。

    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
  • A ボタン

2 つのフィールドの binding-pathvalue に、プロパティの unitTemperature に設定します。

  1. Editor フォルダーに、Resources という名前のフォルダーを作成します。

  2. Resources フォルダーに、temperature_drawer.uxml という名前の UI ドキュメントを作成し、そのコンテンツを以下と置き換えます。

    <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. シーンで空のゲームオブジェクトを作成します。
  2. Hierarchy でゲームオブジェクトを選択します。
  3. PlanetScript.cs を Inspector にドラッグすることで、ゲームオブジェクトに Planet スクリプトコンポーネントを追加します。
  4. Temperature フィールドに数値を入力し、ドロップダウンから単位を選択します。
  5. Convert ボタンを選択して、単位を変換します。Inspector UI で変更を加えると、カスタムコントロールの Temperature プロパティが変更されます。

追加リソース

カスタムコントロールをバインドする
エディター UI のサポート