Day - 07. UI Toolkit 살펴 보기
Unity3D 2021. 11. 5. 00:30이전 시간(https://smilejsu.tistory.com/2332)에 이어서 Toggle을 살펴 보겠습니다
Controls
https://docs.unity3d.com/Manual/UIE-ElementRef.html
https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEngine.UIElements.Toggle.html
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
Toggle | 확인란으로 표시되는 토글 버튼입니다. | UnityEngine.UIElements | None | BaseFieldTraits<bool, UxmlBoolAttributeDescription>의 모든 속성 text |
text : 토글의 오른쪽 레이블입니다.
실습 해보기
이전 코드들도 함께 작성되었습니다
<?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:Template src="/Assets/Editor/Template.uxml" name="Template"/>
<engine:Instance name="player1" template="Template">
<AttributeOverrides element-name="player-name-label" text="Alice" />
</engine:Instance>
<engine:Button text="테스트 버튼"/>
<engine:RepeatButton text="Repeat Button" style="border-color:red; width:auto; height:auto; background-color: red">
</engine:RepeatButton>
<engine:Toggle text="isTest"></engine:Toggle>
</engine:UXML>
토글 버튼이 잘 생겨났네요
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
Scroller | 스크롤 막대입니다. | UnityEngine.UIElements | None | VisualElement의 모든 속성 low-value, height-value, direction value |
low-value: 스크롤러의 최소값
high-value: 스크롤러의 최대값
direction: 수평 또는 수직으로 설정합니다. 기본값은 수직입니다.
value: 스크롤러 커서의 위치
스크롤러가 잘 생성되었네요
아직 핸들을 가지고 움직여지지는 않아요
height속성으로 높이를 좀 키워봤어요
이미지에 넣어볼까요...
그래도 동작은안하네요 따로 무언가 해줘야 하나바요 나중에 알아봐요
<?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:Template src="/Assets/Editor/Template.uxml" name="Template"/>
<engine:Instance name="player1" template="Template">
<AttributeOverrides element-name="player-name-label" text="Alice" />
</engine:Instance>
<engine:Button text="테스트 버튼"/>
<engine:RepeatButton text="Repeat Button" style="border-color:red; width:auto; height:auto; background-color: red">
</engine:RepeatButton>
<engine:Toggle text="isTest"></engine:Toggle>
<engine:Image style="--unity-image: url(/Assets/Images/unity_logo.png)">
<engine:Scroller style="height:200px"/>
</engine:Image>
</engine:UXML>
수평으로도 넣어 봤어요
<engine:Scroller direction="Horizontal"/>
https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEngine.UIElements.SliderDirection.html
https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEngine.UIElements.Scroller.html
다음은 Slider 입니다
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
Slider | 슬라이더 입니다 | UnityEngine.UIElements | None | BaseFieldTraits<float, UxmlFloatAttributeDescription>의 모든 속성 low-value, high-value, direction page-size |
low-value: 슬라이더의 최소값
high-value: 슬라이더의 최대값
direction: 수평 또는 수직으로 설정합니다. 기본값은 수평입니다.
page-size: 슬라이더의 페이지 크기
실습하기
<?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:Template src="/Assets/Editor/Template.uxml" name="Template"/>
<engine:Instance name="player1" template="Template">
<AttributeOverrides element-name="player-name-label" text="Alice" />
</engine:Instance>
<engine:Button text="테스트 버튼"/>
<engine:RepeatButton text="Repeat Button" style="border-color:red; width:auto; height:auto; background-color: red">
</engine:RepeatButton>
<engine:Toggle text="isTest"></engine:Toggle>
<engine:Image style="--unity-image: url(/Assets/Images/unity_logo.png); width:64; height:64;">
</engine:Image>
<engine:Scroller direction="Horizontal"/>
<engine:Slider></engine:Slider>
<engine:Slider direction="Vertical" style="height:100px;"></engine:Slider>
</engine:UXML>
요건 움직이네요
수직으로 했는데 크기가..
height속성으로 조금 크게 만들어 봤습니다
이것도 잘 움직이네요
일단 슬라이더는 요기까지 다음으로 이동!
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
SliderInt | 정수 값에 대한 슬라이더입니다. | UnityEngine.UIElements | None | BaseFieldTraits<int, UxmlIntAttributeDescription>의 모든 속성 low-value, high-value, direction page-size |
ow-value: 슬라이더의 최소값
high-value: 슬라이더의 최대값
direction: 수평 또는 수직으로 설정합니다. 기본값은 수평입니다.
page-size: 슬라이더의 페이지 크기
실습하기
<engine:SliderInt></engine:SliderInt>
약간 느낌이 snap되는 느낌요
이동시 한칸 한칸 이동되는 느낌
수직으로도 해봤습니다
이동시 느낌은 똑같습니다 자석에 붙는거 처럼 딱딱 나눠서 이동되는 느낌
<engine:SliderInt direction="Vertical" style="height:100px"></engine:SliderInt>
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
MinMaxSlider | 사용자가 최소값과 최대값을 지정할 수 있는 슬라이더입니다. | UnityEngine.UIElements | None | BaseField<Vector2>의 모든 속성 low-limit, high-limit, min-value, max-value |
low-limit: 스크롤러의 최소값
high-limit: 스크롤러의 최대값
min-value: 슬라이더 커서의 최소값
max-value: 슬라이더 커서의 최대값
실습하기
오홍.. 모양이 되게 신기 하네요
좌우로 조절할수 있어요
direction이 없는거 보니깐 수직은 안되나바요
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
EnumField | 기본 Enum의 문자열 값을 사용하는 필드입니다. | UnityEditor.UIElements | None | BaseField<Enum>의 모든 속성 type, value |
type:
기본 Enum의 C# 형식을 나타내는 문자열입니다.
형식이 사용자 어셈블리에 있는 경우 어셈블리 이름을 형식 이름에 추가해야 합니다.
MyNamespace.MyEnum, MyAssembly. 유형 문자열은 항상 필수입니다.
value: 필드 값을 나타내는 문자열
실습하기
구글 형님이 있으니깐 괜찮아요
이렇게 하는게 아닌가바요
<!--<engine:EnumField></engine:EnumField>-->
<!--<engine:EnumField label="Dev" type="smilejsu.eType" />-->
<engine:Label name="label" text="tempText"/>
<engine:EnumField label="Test" type="smilejsu.eType, Assembly-CSharp-Editor" />
https://forum.unity.com/threads/enumfield-does-not-work-for-custom-enum-type.678580/
일단 패스 하고 다음에 다시 와서 해봅시다 ㅠ
I have the same issue that an enum field now doesn't work anymore for my editor scripts. Which before was the easiest task, now seems to be a massive pain in the ass, plus a nightmare to debug if the type string / namespace changes, which happens quite often, mostly in the early stages of a project.
I use the UI Builder to check UI Toolkit out for the first time, the first field is an enum and my world falls apart already. Here is the enum definition:
Here is my class that contains the enum:
Code (CSharp):
- namespace Source.Components.Common
- {
- [RequireComponent(typeof(Image))]
- public class ImageFX : MonoBehaviour
- {
- public enum Effect
- {
- Glow,
- Flash,
- Shine,
- GlowSoftMask,
- FlashSoftMask,
- }
- [...]
- }
- }
I get a popup type attribute invalid, make sure to include assembly name.
I tried Source.Components.Common.ImageFX.Effect as-well.
The generated UXML window shows as my new editor layout, but the enum field has no values.
PS: I also tried to fill the enum popup via code, which would be fine for me, but this doesn't seem to work either:
Code (CSharp):
- [CustomEditor(typeof(ImageFX))]
- public class ImageFxEditor : UnityEditor.Editor
- {
- public void OnEnable()
- {
- VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Source/Components/Common/Editor/ImageFX.uxml");
- var ui = visualTree.Instantiate();
- var enumField = ui.Q<EnumField>("effect");
- enumField.Init(ImageFX.Effect.Glow);
- }
- }
일단 패스요 ~
[추가]
EnumField 예제
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:EnumField label="UXML Field" name="the-uxml-field" include-obsolete-values="false"/>
</UXML>
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;
// VisualElements objects can contain other VisualElement following a tree hierarchy.
VisualElement label = new Label("Hello World! From C#");
root.Add(label);
// 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,
// initialize it with an Enum type,
// and assign it its value.
var uxmlField = container.Q<EnumField>("the-uxml-field");
uxmlField.Init(TextAlignment.Center);
uxmlField.value = TextAlignment.Left;
// Create a new field, disable it, and give it a style class.
var csharpField = new EnumField("C# Field", TextAlignment.Center);
//csharpField.SetEnabled(false);
csharpField.AddToClassList("some-styled-field");
csharpField.value = uxmlField.value;
container.Add(csharpField);
// Mirror value of uxml field into the C# field.
uxmlField.RegisterCallback<ChangeEvent<Enum>>((evt) =>
{
csharpField.value = evt.newValue;
});
}
}
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
MaskField | 사용자가 값 그룹을 선택할 수 있는 팝업 메뉴입니다. | UnityEditor.UIElements | None | BaseField<Enum>의 모든 속성 choices, value |
choices: 팝업 메뉴에 표시할 최대 32개의 선택 항목을 쉼표로 구분한 목록
value: 필드 값을 32비트 마스크로 나타내는 정수입니다
와.. 이것도 모르겠네요
부족한게 너무 많은 접니다..
일단 넘어가죠 이것도...
[추가]
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:MaskField label="UXML Field" name="the-uxml-field" />
</UXML>
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System;
using System.Collections.Generic;
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;
// VisualElements objects can contain other VisualElement following a tree hierarchy.
VisualElement label = new Label("Hello World! From C#");
root.Add(label);
// 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<MaskField>("the-uxml-field");
uxmlField.value = 1;
uxmlField.choices = new List<string> { "First", "Second", "Third" };
// Create a new field, disable it, and give it a style class.
var csharpField = new MaskField("C# Field");
//csharpField.SetEnabled(false);
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;
});
}
}
아 이제 알겠습니다. 예, 선택은 내부적입니다. 그러나 그렇게해서는 안됩니다. 버그입니다. 수정될 것입니다. 지금은 C#으로 MaskField를 구성해야 합니다.
Controls
Element | Function | Namespace | Permitted child elements (허용되는 자식 요소) | Attributes |
LayerField | 사용자가 레이어를 선택할 수 있는 팝업 메뉴 에서. | UnityEditor.UIElements | None | BaseField<int>의 모든 속성 value |
레이어 : https://docs.unity3d.com/Manual/Layers.html
value: 필드 값(선택한 레이어 번호)을 나타내는 정수입니다.
이것도 이렇게 쓰는게 아닌가바요;;
이거 하나만 쓰는방법 알면 다 같은 방식일거 같은데 지금 찾아서 하기에는 앞으로 가야할길이 많아서
일단 킵 해둡시다
[추가]
<?xml version="1.0" encoding="utf-8"?>
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<uie:LayerField label="UXML Field" name="the-uxml-field" />
</UXML>
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System;
using System.Collections.Generic;
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;
// VisualElements objects can contain other VisualElement following a tree hierarchy.
VisualElement label = new Label("Hello World! From C#");
root.Add(label);
// 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<LayerField>("the-uxml-field");
uxmlField.value = 1;
// Create a new field, disable it, and give it a style class.
var csharpField = new LayerField("C# Field");
csharpField.SetEnabled(false);
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;
});
}
}
후 안되겠네요 오늘은 여기까지 해야겠어요
내일은 LayerMaskField 부터 살펴 보겠습니다
내일 시작 하자마자 털리고 시작 하겠네요 멘탈 털털털
그럼 오늘도 긴글 읽어 주시느라 수고 하셨습니다
내일 봐요
사용방법을 알아내서 추가 해놨어요 ~
[추가]
결론적으로 헤멘이유는 UnityEditor.UIElements 을 잘 살펴 보지 않았기 때문
나중에 볼것
UIBuilder 관련
'Unity3D' 카테고리의 다른 글
Day - 09. UI Toolkit 살펴 보기 (0) | 2021.11.06 |
---|---|
Day - 08. UI Toolkit 살펴 보기 (0) | 2021.11.05 |
Day - 06. UI Toolkit 살펴 보기 (0) | 2021.11.04 |
ngui joystick (0) | 2021.11.04 |
Day - 05. UI Toolkit 살펴 보기 (0) | 2021.11.03 |