UI 툴킷의 가장 기본적인 빌딩 블록은 시각적 요소입니다. 시각적 요소는 부모-자식 관계가 있는 계층 구조 트리로 정렬됩니다. 아래 다이어그램은 계층 구조 트리의 단순화된 예와 UI 툴킷의 렌더링된 결과를 보여줍니다.
VisualElement 클래스는 시각적 트리의 모든 노드에 대한 기반입니다. VisualElement
기본 클래스에는 스타일, 레이아웃 데이터, 이벤트 핸들러와 같은 모든 컨트롤에 대한 일반 프로퍼티가 포함되어 있습니다. 시각적 요소에는 자식 및 자손 시각적 요소가 있을 수 있습니다. 예를 들어 위 다이어그램에서 첫 번째 Box
시각적 요소에는 Label
, Checkbox
, Slider
라는 세 가지 자식 시각적 요소가 있습니다.
스타일시트를 통해 시각적 요소의 형상을 커스터마이즈할 수 있습니다. 또한 이벤트 콜백을 사용하여 시각적 요소의 동작을 수정할 수도 있습니다.
VisualElement
는 컨트롤과 같은 추가 동작 및 기능을 정의하는 서브 클래스로 파생됩니다. UI 툴킷에는 특수 동작이 포함된 다양한 빌트인 컨트롤이 포함되어 있습니다. 예를 들어 다음 항목을 빌트인 컨트롤로 사용할 수 있습니다.
시각적 요소를 서로 결합하고 해당 동작을 수정하여 커스텀 컨트롤을 생성할 수도 있습니다. 빌트인 컨트롤 리스트는 컨트롤 레퍼런스 페이지를 참조하십시오.
패널은 시각적 트리의 부모 오브젝트입니다. 트리 내부의 시각적 요소가 렌더링되려면 시각적 트리가 패널에 연결되어야 합니다. 모든 패널은 에디터 창과 같이 창에 속합니다. 또한 패널은 포커스 컨트롤 그리고 시각적 트리에 대한 이벤트 디스패치를 처리합니다.
시각적 트리의 모든 요소에는 시각적 트리를 포함하는 패널에 대한 직접 레퍼런스가 있습니다. VisualElement
와 패널의 연결을 확인하기 위해 이 요소의 panel
프로퍼티를 테스트할 수 있습니다. 시각적 요소가 연결되지 않은 경우 테스트는 null
을 반환합니다.
시각적 트리에서 요소의 드로잉 순서는 뎁스 우선 검색을 따릅니다. 자식 시각적 요소는 부모 요소 위에 나타납니다. 또한 자식 요소는 형제 리스트의 순서로 그려집니다. 드로잉 순서는 다음과 같습니다.
아래 다이어그램은 이전 예제의 드로잉 순서를 보여줍니다.
시각적 요소의 드로잉 순서를 변경하려면 다음 함수를 사용하십시오.
형제 시각적 요소의 경우 다음 함수를 사용하십시오.
UI 툴킷은 스타일 프로퍼티의 레이아웃 파라미터를 기반으로 개별 요소의 포지션 및 크기를 자동으로 계산하는 강력한 레이아웃 시스템을 사용합니다. 자세한 내용은 레이아웃 엔진 페이지를 참조하십시오.
UI 툴킷에는 다음과 같은 두 가지 타입의 좌표가 있습니다.
각 시각적 요소는 위치를 계산하는 데 사용되는 좌표 시스템을 결정합니다. 요소 스타일시트에서 사용할 좌표 시스템을 구성할 수 있습니다.
다음 코드는 코드를 통해 시각적 요소의 포지션 및 좌표 공간을 설정하는 방법을 보여줍니다.
var newElement = new VisualElement();
newElement.style.position = Position.Relative;
newElement.style.left = 15;
newElement.style.top = 35;
요소의 원점은 왼쪽 상단 코너입니다.
레이아웃 시스템은 각 요소의 VisualElement.layout
프로퍼티(Rect
타입)를 계산하며, 여기에는 요소의 최종 포지션이 포함됩니다. 이때 요소의 상대 또는 절대 포지션이 고려됩니다.
layout.position
은 점으로 표현되며, 해당 부모의 좌표 공간을 기준으로 합니다.
각 VisualElement
에는 요소의 포지션 및 회전에 로컬 오프셋을 추가하는 데 사용할 수 있는 트랜스폼 프로퍼티(ITransform
)가 있습니다. 오프셋은 계산된 레이아웃 프로퍼티에 표시되지 않습니다. 기본적으로 transform
은 ID입니다.
worldBound
프로퍼티를 사용하여 VisualElement
의 최종 창 공간 좌표를 검색해서 가져오고, 레이아웃 포지션과 트랜스폼을 모두 고려하십시오. 이 포지션에는 창 헤더의 높이가 포함됩니다.
다음 코드 샘플은 상대 위치 지정과 절대 위치 지정 간의 차이를 보여줍니다. 또한 자동 레이아웃 시스템을 사용하여 창에 상자를 추가하고 해당 포지션을 계산합니다. 한 상자는 25 px
의 상대 오프셋을 보여주고, 또 다른 상자는 25 px, 25 px
의 절대 포지션을 보여줍니다.
이 예제가 동작하는 방식을 확인하려면 다음 단계를 따르십시오.
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class PositioningTestWindow : EditorWindow
{
[MenuItem("Window/UI Toolkit/Positioning Test Window")]
public static void ShowExample()
{
var wnd = GetWindow<PositioningTestWindow>();
wnd.titleContent = new GUIContent("Positioning Test Window");
}
public void CreateGUI()
{
for (int i = 0; i < 2; i++)
{
var temp = new VisualElement();
temp.style.width = 70;
temp.style.height = 70;
temp.style.marginBottom = 2;
temp.style.backgroundColor = Color.gray;
rootVisualElement.Add(temp);
}
// Relative Positioning
var relative = new Label("Relative\nPos\n25, 0");
relative.style.width = 70;
relative.style.height = 70;
relative.style.left = 25;
relative.style.marginBottom = 2;
relative.style.backgroundColor = new Color(0.2165094f, 0, 0.254717f);
rootVisualElement.Add(relative);
for (int i = 0; i < 2; i++)
{
var temp = new VisualElement();
temp.style.width = 70;
temp.style.height = 70;
temp.style.marginBottom = 2;
temp.style.backgroundColor = Color.gray;
rootVisualElement.Add(temp);
}
// Absolute Positioning
var absolutePositionElement = new Label("Absolute\nPos\n25, 25");
absolutePositionElement.style.position = Position.Absolute;
absolutePositionElement.style.top = 25;
absolutePositionElement.style.left = 25;
absolutePositionElement.style.width = 70;
absolutePositionElement.style.height = 70;
absolutePositionElement.style.backgroundColor = Color.black;
rootVisualElement.Add(absolutePositionElement);
}
}
VisualElement.layout.position
및 VisualElement.transform
프로퍼티는 로컬 좌표 시스템과 부모 좌표 시스템 간의 변환 방식을 정의합니다.
VisualElementExtensions 정적 클래스는 좌표 시스템 간에 점과 사각형을 변환하는 다음의 확장 메서드를 제공합니다.
WorldToLocal
은 Vector2
또는 Rect
를 Panel
공간에서 요소 내 레퍼렌셜로 변환합니다.LocalToWorld
는 Vector2
또는 Rect
를 Panel
공간 레퍼렌셜로 변환합니다.ChangeCoordinatesTo
는 한 요소의 로컬 공간에 있는 Vector2
또는 Rect
를 다른 로컬 공간으로 변환합니다.