Day - 09. UI Toolkit 살펴 보기
Unity3D 2021. 11. 6. 01:40이전 시간에 이어 IntegerField 부터 살펴 보겠습니다
Controls
https://docs.unity3d.com/Manual/UIE-ElementRef.html
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
IntegerField | 정수(32비트) 값을 허용하는 텍스트 필드입니다. | UnityEngine.UIElements | None | BaseFieldTraits<int, UxmlIntAttributeDescription>의 모든 속성 |
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:IntegerField label="UXML Field" name="the-uxml-field" />
</UXML>
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
public class TestWindow : EditorWindow
{
[MenuItem("Window/UI Toolkit/TestWindow")]
public static void ShowExample()
{
TestWindow wnd = GetWindow<TestWindow>();
wnd.titleContent = new GUIContent("TestWindow");
}
public void CreateGUI()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement;
// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/TestWindow.uxml");
VisualElement labelFromUXML = visualTree.Instantiate();
root.Add(labelFromUXML);
}
}
변하는 값을 출력하기
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System;
public class TestWindow : EditorWindow
{
[MenuItem("Window/UI Toolkit/TestWindow")]
public static void ShowExample()
{
TestWindow wnd = GetWindow<TestWindow>();
wnd.titleContent = new GUIContent("TestWindow");
}
public void CreateGUI()
{
// Each editor window contains a root VisualElement object
VisualElement root = rootVisualElement;
// Import UXML
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/TestWindow.uxml");
VisualElement container = visualTree.Instantiate();
root.Add(container);
// Get a reference to the field from UXML and assign it its value.
var uxmlField = container.Q<IntegerField>("the-uxml-field");
//uxmlField.value = new Texture2D(10, 10) { name = "new_texture" };
// Create a new field, disable it, and give it a style class.
var csharpField = new IntegerField("C# Field");
csharpField.SetEnabled(true);
csharpField.AddToClassList("some-styled-field");
csharpField.value = uxmlField.value;
container.Add(csharpField);
// Mirror value of uxml field into the C# field.
uxmlField.RegisterCallback<ChangeEvent<int>>((evt) =>
{
csharpField.value = evt.newValue;
//Debug.Log(evt.newValue);
Debug.Log(evt.newValue);
});
}
}
Controls
https://docs.unity3d.com/Manual/UIE-ElementRef.html
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
LongField | 긴 정수(64비트) 값을 허용하는 텍스트 필드입니다. | UnityEngine.UIElements | None | BaseFieldTraits<long, UxmlLongAttributeDescription>의 모든 속성 |
IntField와 비슷하네요
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:LongField label="UXML Field" name="the-uxml-field" />
</UXML>
FloatField, DoubleField 는 비슷하니 패스
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
Vector2Field | Vector2의 값을 편집하기 위해 부동 소수점 값을 허용하는 두 개의 텍스트 필드 집합입니다. | UnityEngine.UIElements | None | BaseField<Vector2>의 모든 속성 x: X 좌표 값 y: Y 좌표 값 |
갑자기
두가지 궁금증이 생겼다
첫째, <uie는 언제 쓰는것인가?
<!--<uie:Label text="test"/>-->
<Label text="test" />
<uie:LayerMaskField />
둘째, 기본 UI Document를 생성했을때 생성되는 uxml은 왜 이런 모양이지
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:engine="UnityEngine.UIElements"
xmlns:editor="UnityEditor.UIElements"
xsi:noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd"
>
</engine:UXML>
이것과 다른게 무엇일까...
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
</UXML>
네임스페이스를 더 쉽게 지정하기 위해 네임스페이스 접두사를 정의할 수 있습니다.
예를 들어 xmlns:engine="UnityEngine.UIElements"는 engine 접두사를 UnityEngine.UIElements로 정의합니다.
네임스페이스 접두사가 정의되면 이를 사용하여 네임스페이스를 지정할 수 있습니다.
예를 들어 <engine:Button />은 <UnityEngine.UIElements:Button />과 동일합니다.
xml namespace로 UnityEngine.UIElements가 추가 되었기 때문에
<Label /> 을 사용할수 있는듯 하다
그럼 xmlns:uie는 무엇일까
xmlns:접두사 인듯 하다
접두사는 사용자에 의해 지정되는 네임스페이스의 속성 이름이다
즉, 네임스페이스 식별자이다
그럼 <uie:LayerMaskField />되고 <uie:Label /> 은 안되는 이유는?혹시 LayerMaskField는 Editor이고 Label은 Engine네임스페이여서?
그러하다 !
그냥 감으론만 그런줄 알고 진행중이였는데 찾아보니 확신이 생겼다
굳 ~
다음꺼 진행 하자
Vector2Field까지 했으니 다음은 Vector2IntField 인데 이거 비슷한애들이 너무 많아서 그냥 넘어가도록 한다
RectField를 보자
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
RectField | 사각형 값을 편집하기 위해 부동 소수점 값을 허용하는 4개의 텍스트 필드 집합입니다. | UnityEditor.UIElements | None | BaseField<Rect>의 모든 속성 x: 왼쪽 상단 모서리 X 좌표의 값 y: 왼쪽 상단 모서리 Y 좌표의 값 w: 사각형의 너비 h: 직사각형의 높이 |
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:RectField />
</UXML>
RectIntField 는 비슷하니 패스
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
BoundsField | 경계 사각형의 값을 편집하기 위해 부동 소수점 값을 허용하는 6개의 텍스트 필드 집합입니다. | UnityEditor.UIElements | None | BaseField<Bounds>의 모든 속성 cx: 중심 X 좌표의 값 cy: 중심 Y 좌표의 값 cz: 중심 Z 좌표 값 ex: 익스텐트 X 좌표 값 ey: 범위 Y 좌표 값 ez: 범위 Z 좌표의 값 |
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:BoundsField />
</UXML>
BoundsIntField도 비슷하므로 패스
Complex widgets
complex widgets에는 모두 UnityEditor.UIElements 에 속해 있다
complex widgets
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
PropertyField | 값을 편집할 레이블 및 필드입니다. | UnityEditor.UIElements | None | VisualElement의 모든 속성 binding-path: 이 요소가 바인딩된 속성의 경로 레이블: 필드의 레이블 |
Monster.cs 파일을 생성한다
serialized 필드로 int maxHp를 정의 한다
빈오브젝트를 생성하고 Monster 컴포넌트를 부착 한다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Monster : MonoBehaviour
{
public int maxHp;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
MonsterEditor.cs 파일을 생성한다
CreateInspectorGUI를 재정의 한다
다음과 같이 작성한다
using UnityEditor;
using UnityEngine.UIElements;
[CustomEditor(typeof(Monster))]
public class MonsterEditor : Editor
{
public override VisualElement CreateInspectorGUI()
{
return new VisualElement();
}
}
return new VisualElement();
이것은 빈 HTML <div>와 비슷하다
그래서 Monter게임 오브젝트를 선택하면 빈 인스펙터창을 볼수 있다
MonsterEditor.uxml파일을 만들고 Label하나를 추가하자
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<Label text="Custom Monster Inspector"/>
</UXML>
그리고 MonsterEditor.cs파일을 수정한다
using UnityEditor;
using UnityEngine.UIElements;
[CustomEditor(typeof(Monster))]
public class MonsterEditor : Editor
{
public override VisualElement CreateInspectorGUI()
{
var treeAsset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/MonsterEditor.uxml");
var container = treeAsset.CloneTree();
return container;
}
}
이제 인스펙터창에 Label이 표시된것을 볼수 있다
PropertyField는 기본 인스펙터에 매칭된다
MonsterEditor.uxml을 수정하자
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<Label text="Custom Monster Inspector"/>
<uie:PropertyField binding-path="maxHp" label="test max hp"/>
</UXML>
바인딩된 필드 (maxHp)에 label속성이 잘 적용되었다
오늘은 요기까지...
내일은 Complex widgets에 대해 조금더 자세히 공부해봅시다
참고
https://docs.unity3d.com/kr/2018.4/Manual/UIE-UXML.html
https://docs.unity3d.com/kr/2021.1/Manual/UIE-WritingUXMLTemplate.html
https://myeonguni.tistory.com/1110
https://docs.unity3d.com/Manual/UIE-ElementRef.html
https://exploringunity.com/posts/monster-inspector/
https://hacchi-man.hatenablog.com/entry/2020/11/04/220000
https://gametorrahod.com/uielements-custom-marker/
https://github.com/Unity-Technologies/UIElementsExamples/tree/master/Assets/Examples/Editor
'Unity3D' 카테고리의 다른 글
Free Unity Asset 2021 (0) | 2021.11.07 |
---|---|
Day - 10. UI Toolkit 살펴 보기 with UI Builder (0) | 2021.11.06 |
Day - 08. UI Toolkit 살펴 보기 (0) | 2021.11.05 |
Day - 07. UI Toolkit 살펴 보기 (0) | 2021.11.05 |
Day - 06. UI Toolkit 살펴 보기 (0) | 2021.11.04 |