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속성으로 높이를 좀 키워봤어요 

이미지에 넣어볼까요...

https://forum.unity.com/threads/button-with-icon.733343/

그래도 동작은안하네요 따로 무언가 해줘야 하나바요 나중에 알아봐요 

<?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/

 

Bug - EnumField does not work for custom Enum type

Hi, I found that my own enum type does not work in EnumField in UXML. Here is minimul reproducible code: TestWindow.uxml

forum.unity.com

일단 패스 하고 다음에 다시 와서 해봅시다 ㅠ

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):

 

  1. namespace Source.Components.Common
  2. {
  3.     [RequireComponent(typeof(Image))]
  4.     public class ImageFX : MonoBehaviour
  5.     {
  6.         public enum Effect
  7.         {
  8.             Glow,
  9.             Flash,
  10.             Shine,
  11.             GlowSoftMask,
  12.             FlashSoftMask,
  13.         }
  14.         [...]
  15.     }
  16. }

 

 

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):

  1.     [CustomEditor(typeof(ImageFX))]
  2.     public class ImageFxEditor : UnityEditor.Editor
  3.     {
  4.         public void OnEnable()
  5.         {
  6.             VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Source/Components/Common/Editor/ImageFX.uxml");
  7.             var ui = visualTree.Instantiate();
  8.             var enumField = ui.Q<EnumField>("effect");
  9.             enumField.Init(ImageFX.Effect.Glow);
  10.         }
  11.     }

 

 

일단 패스요 ~

 

[추가]

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

https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEditor.UIElements.MaskField.html?q=MaskField 

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를 구성해야 합니다.

 

https://forum.unity.com/threads/maskfield-choices-internal.672670/


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 관련 

https://developers.10antz.co.jp/archives/873

반응형

'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
: