Unity3D :将自定义控件绑定到自定义数据类型
推荐:将NSDT场景编辑器就加入你的3D工具链
3D工具集:NSDT简石数字孪生
将自定义控件绑定到自定义数据类型
版本: 2021.3+
此示例演示如何将自定义控件绑定到自定义数据类型。
示例概述
此示例基于三个内置控件创建自定义数据类型和自定义控件。它将自定义控件绑定到自定义数据类型。抽屉在摄氏度和华氏度之间转换。

您可以在此 GitHub 存储库中找到此示例创建的已完成文件。
先决条件
本指南适用于熟悉 Unity 编辑器的开发人员,用户界面
工具包和 C# 脚本。在开始之前,请熟悉以下内容:
- 用户体验
PropertyField
创建自定义数据类型
创建自定义数据类型 ,并将其用作序列化属性。Temperature
- 使用任何模板创建 Unity 项目。
- 创建一个名为存储所有文件的文件夹。
bind-custom-data-type
创建一个名为的 C# 脚本,并将其内容替换为以下内容:Temperature.cs
using System;
namespace UIToolkitExamples
{
public enum TemperatureUnit
{
Celsius,
Farenheit
}
[Serializable]
public struct Temperature
{
public double value;
public TemperatureUnit unit;
}
}
创建一个名为的 C# 脚本,并将其内容替换为以下内容:PlanetScript.cs
using UnityEngine;
namespace UIToolkitExamples
{
public class PlanetScript : MonoBehaviour
{
public Temperature coreTemperature;
}
}
创建自定义控件
创建自定义编辑器和自定义编辑器Planet
物业抽屉
为。Temperature
在自定义属性抽屉中,实现一个按钮,该按钮通过写入 SerializedProperty
的属性(使用 doubleValue
和 enumValueIndex
),然后调用 SerializedObject.ApplyModifiedProperties()
在华氏度和摄氏度之间转换温度。
自定义属性抽屉被视为自定义控件。它是一个以自定义方式运行的内置控件。
- 创建一个名为 的文件夹。
Editor
在“编辑器”文件夹中,创建一个名为的 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"));
}
}
}
In the Editor folder, create a C# script named and replace its contents with the following: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 文件:
- 双场
- 安努姆菲尔德
- 一个按钮
将两个字段的 设置为 和 属性。binding-pathvalueunitTemperature
- 在编辑器文件夹中,创建一个名为 的文件夹。
Resources
在“资源”文件夹中,创建一个名为的 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>
测试绑定
- 创建一个空的游戏对象
在一个现场
. - 在层次结构中,选择游戏对象。
- 将 PlanetScript.cs 拖到检查员
.这会将星球脚本组件添加到游戏对象。 - 在“温度”字段中输入一个数字,然后从下拉列表中选择一个单位。
- 选择“转换”按钮以在单位之间进行转换。如果在检查器 UI 中进行更改,则自定义控制的属性会更改。
Temperature
由3D建模学习工作室整理翻译,转载请注明出处!