バージョン: 2021.3 以降
この例では、カスタムコントロールをカスタムデータ型にバインドする方法を説明します。
この例では、3 つのビルトインコントロールに基づき、カスタムデータ型とカスタムコントロールを作成します。カスタムコントロールは、カスタムデータ型にバインドされます。ドロワーは、Celsius (摂氏) と Fahrenheit (華氏) の変換を行います。
この例で作成するすべてのファイルは、GitHub リポジトリ にあります。
このガイドは、Unity エディター、UI Toolkit、および C# スクリプトに精通している開発者を対象としています。始める前に、以下をよく理解してください。
カスタムデータ型 Temperature
を作成し、シリアル化されたプロパティとして使用します。
任意のテンプレートで Unity プロジェクトを作成します。
bind-custom-data-type
というフォルダーを作成し、すべてのファイルを保存します。
Temperature.cs
という名の C# スクリプトを作成し、そのコンテンツを以下に置き換えます。
using System;
namespace UIToolkitExamples
{
public enum TemperatureUnit
{
Celsius,
Farenheit
}
[Serializable]
public struct Temperature
{
public double value;
public TemperatureUnit unit;
}
}
PlanetScript.cs
という名の C# スクリプトを作成し、そのコンテンツを以下に置き換えます。
using UnityEngine;
namespace UIToolkitExamples
{
public class PlanetScript : MonoBehaviour
{
public Temperature coreTemperature;
}
}
Planet
のカスタムエディターと、 Temperature
のカスタムプロパティドロワーを作成します。
カスタムプロパティドロワーで、温度を華氏と摂氏間で変換するボタンを実装します。それを行うには、SerializedProperty
(doubleValue
と enumValueIndex
を使用) のプロパティに書き込み、それから、SerializedObject.ApplyModifiedProperties()
を呼び出します。
カスタムプロパティドロワーは、カスタムコントロールとして扱われます。これは、カスタムの方法で動作するビルトインのコントロールです。
Editor
という名前のフォルダーを作成します。
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"));
}
}
}
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 ファイルを作成します。
2 つのフィールドの binding-path
を Temperature
プロパティの value
と unit
に設定します。
Editor フォルダーに、Resources
という名前のフォルダーを作成します。
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>
Temperature
プロパティが変更されます。Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.