버전:2021.3+
이 예에서는 커스텀 컨트롤을 커스텀 데이터 타입에 바인딩하는 방법을 보여 줍니다.
이 예에서는 세 가지 빌트인 컨트롤을 기반으로 커스텀 데이터 타입과 커스텀 컨트롤을 만듭니다.커스텀 컨트롤을 커스텀 데이터 타입에 바인딩합니다.드로어는 섭씨와 화씨 사이를 전환합니다.
이 예제에서 생성한 완성된 파일은 GitHub 저장소에 있습니다.
이 가이드는 Unity 에디터, UI 툴킷, 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 파일을 만듭니다.
두 필드의 ’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>