버전: 2021.3+
이 예에서는 커스텀 컨트롤을 커스텀 데이터 유형에 바인딩하는 방법을 보여 줍니다.
이 예제에서는 세 가지 빌트인 컨트롤을 기반으로 커스텀 데이터 유형과 커스텀 컨트롤을 생성합니다. 커스텀 컨트롤을 커스텀 데이터 유형에 바인딩합니다. 드로어가 Celsius와 Fahrenheit 사이로 전환됩니다.
이 예제에서 완성된 파일은 이 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()를 호출하여 Fahrenheit와 Celsius 간 온도를 전환하는 버튼을 구현합니다.
커스텀 프로퍼티 드로어는 커스텀 컨트롤로 간주됩니다. 이는 커스텀 방식으로 작동하는 빌트인 컨트롤입니다
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__(사용자 인터페이스) 사용자가 애플리케이션과 상호 작용하도록 해 줍니다. Unity는 현재 3개의 UI 시스템을 지원합니다. 자세한 정보
See in Glossary 문서를 생성하고 해당 콘텐츠를 다음과 같이 바꿉니다.
<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 프로퍼티가 변경됩니다.