【Unity3D】UI Toolkit容器

little_fat_sheep發表於2023-10-18

1 前言

UI Toolkit簡介 中介紹了 UI Builder、樣式屬性、UQuery、Debugger,UI Toolkit元素 中介紹了 Label、Button、TextField、Toggle、Radio Button、Slider、Progress Bar、Dropdown、Foldout 等元素,UI Toolkit樣式選擇器 中介紹了簡單選擇器、複雜選擇器、偽類選擇器等樣式選擇器,本文將介紹 UI Toolkit 中的容器,主要包含 VisualElement、ScrollView、ListView、GroupBox 等,官方介紹詳見→UXML elements reference

2 VisualElement(空容器)

​ VisualElement 是一個空容器,便於組織和管理元素,官方介紹見→UXML element VisualElement

1)屬性介紹

img

  • View Data Key:用於檢視資料持久化(如:樹展開狀態、滾動位置、縮放級別),作為檢視資料儲存 / 載入的鍵,如果不設定此鍵將禁用該容器的永續性。
  • Picking Mode:判斷是否可以在 mouseEvents 期間選擇此容器。
  • Tooltip:滑鼠懸停到該容器上時彈出的提示文字。
  • Usage Hints:預期使用模式,便於系統加速某些操作。
  • Tab Index:用於對焦點環中的焦點物件進行排序。
  • Focusable:容器是否能獲得焦點。

​ 說明:View Data Key、Picking Mode、Tooltip、Usage Hints、Tab Index、Focusable 都是基類屬性,後文若出現這些屬性將不再贅述。

2)獲取根 VisualElement 容器

VisualElement rootVisualElement = GetComponent<UIDocument>().rootVisualElement;

3)註冊事件回撥(RegisterCallback)

​ RegisterCallbackDemo.cs

using UnityEngine;
using UnityEngine.UIElements;

public class RegisterCallbackDemo : MonoBehaviour {
    private void Awake() {
        VisualElement rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
        rootVisualElement.RegisterCallback<MouseDownEvent>(OnClickDown);
        rootVisualElement.RegisterCallback<ClickEvent>(OnClick);
    }

    private void OnClickDown(MouseDownEvent e) { // 滑鼠按下時事件回撥
        Debug.Log("mousePosition=" + e.mousePosition + ", pressedButtons=" + e.pressedButtons); // 1:左鍵, 2:右鍵, 4:中鍵
    }

    private void OnClick(ClickEvent e) { // 滑鼠左鍵點選時事件回撥
        Debug.Log("target=" + e.target);
    }
}

​ 說明:註冊的事件主要有以下幾種,官方介紹見→Event reference

  • MouseDownEvent:滑鼠按下時觸發的事件。
  • MouseUpEvent:滑鼠抬起時觸發的事件。
  • ClickEvent:滑鼠左鍵點選時觸發的事件。
  • MouseOverEvent:滑鼠進入元素時觸發的事件。
  • MouseOutEvent:滑鼠離開元素時觸發的事件。
  • MouseMoveEvent:滑鼠移動時觸發的事件。
  • MouseEnterEvent:滑鼠進入元素或其子元素時觸發的事件。
  • MouseLeaveEvent:滑鼠離開元素和其所有子元素時觸發的事件。
  • MouseCaptureEvent:處理器開始捕獲滑鼠後觸發的事件。
  • MouseCaptureOutEvent:處理器停止捕獲滑鼠後觸發的事件。
  • MouseEnterWindowEvent:滑鼠進入視窗時觸發的事件。
  • MouseLeaveWindowEvent:滑鼠離開視窗時觸發的事件。
  • WheelEvent:滑鼠滑輪滾動時觸發的事件。

4)新增事件操作器(AddManipulator)

​ ManipulatorDemo.cs

using UnityEngine;
using UnityEngine.UIElements;

public class ManipulatorDemo : MonoBehaviour {
    private VisualElement rootVisualElement;

    private void Awake() {
        rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
        Clickable leftClickManipulator = new Clickable(OnCtrlDoubleClicked);
        leftClickManipulator.activators.Clear();
        leftClickManipulator.activators.Add(new ManipulatorActivationFilter() {
            button = MouseButton.LeftMouse, // 滑鼠左鍵
            clickCount = 2, // 點選次數
            modifiers = EventModifiers.Control // 按鍵
        });
        rootVisualElement.AddManipulator(leftClickManipulator);
    }

    private void OnCtrlDoubleClicked(EventBase e) { // Ctrl+Double Click事件回撥
        Debug.Log("OnCtrlDoubleClicked");
    }
}

3 ScrollView(滾動容器)

1)屬性介紹

​ ScrollView 是一個滾動容器,官方介紹見→UXML element ScrollView

img

  • Mode:控制使用者滾動內容的方式,取值有 Vertical(垂直滾動)、Horizontal(水平滾動)、Vertical And Horizontal(垂直和水平滾動)。
  • Nested Interaction Kind:滑動到邊界後的行為,取值有 default(反彈)、Stop Scrolling(停止滑動)、Forward Scrolling(繼續向前滑動)。
  • Horizontal Scroller Visibility:水平捲軸的可見性,取值有 Auto(僅在內容顯示不下時才顯示滑動條)、Always Visible(一直可見)、Hidden(一直隱藏)。
  • Vertical Scroller Visibility:垂直捲軸的可見性,取值有 Auto(僅在內容顯示不下時才顯示滑動條)、Always Visible(一直可見)、Hidden(一直隱藏)。
  • Horizontal Page Size:控制水平滑動的速度。
  • Vertical Page Size:控制垂直滑動的速度。
  • Touch Scroll Type:觸控滑動型別,Unrestricted(不受約束的)、Elastic(彈性的)、Clamped(夾緊的)。
  • Scroll Deceleration Rate:滑動停止時的減速度(速度的導數,為 0 時立刻停止滑動)。
  • Elasticity:滑動到邊界時的彈性值。

2)新增元素

​ 將元素拖拽到 ScrollView 上,會自動放在其 unity-content-container 元素下面,如下。

img

​ 也可以透過以下程式碼新增元素。

VisualElement rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
ScrollView scrollview = rootVisualElement.Q<ScrollView>();
scrollview.Add(new Label("LabelContent"));

4 ListView(列表)

​ ListView 是一個列表容器,官方介紹見→UXML element ListView

1)屬性介紹

img

  • BindingPath:目標屬性繫結的路徑。
  • Fixed Item Height:列表中 item 的高度,以畫素為單位。
  • Virtualization Method:設定 item 高度是固定的還是動態的,取值有 Fixed Height(固定高度)、Dynamic Height(動態高度)。
  • Show Border:是否顯示邊框。
  • Selection Type:選擇型別,取值有 None(禁止選中)、Single(只能選中單個 item)、Multiple(可以選中多個 item)。
  • Show Alternation Row Backgrounds:顯示交替行背景,取值有 None(不顯示交替行背景)、Content Only(有內容時才顯示交替行背景)、All(一直顯示交替行背景)。
  • Show Foldout Header:是否顯示摺疊頁首。
  • Header Title:頁首標題。
  • Show Add Remove Footer:是否顯示新增 / 刪除頁尾,如果顯示,在頁尾會出現 "+" 和 "-" 按鈕。
  • Reorderable:是否允許 item 重排序。
  • Reorder Mode:重排序模式,取值有 Simple(在重排序時顯示標準的藍線拖動器)、Animated(在每個 item 之前新增拖拽控制程式碼,可以用來拖拽單個 item)。
  • Show Bound Collection Size:是否顯示 item 數。
  • Horizontal Scrolling:是否可以水平滑動。

2)ListView 的使用

​ ListViewDemo.cs

using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;

public class ListViewDemo : MonoBehaviour {
    private VisualElement root; // 根容器
    private ListView listView; // 列表
    private string[] itemsTitle = new string[] {"First", "Second", "Third", "Fourth"}; // item的標題
    private int[] itemsData = new int[]{0, 1, 2, 3}; // item的數值

    private void Awake() {
        root = GetComponent<UIDocument>().rootVisualElement;
        listView = root.Q<ListView>();
        listView.fixedItemHeight = 60;
        listView.itemsSource = itemsData;
        listView.makeItem += MakeItem;
        listView.bindItem += BindItem;
        listView.onSelectionChange += OnSelectionChange;
    }

    private VisualElement MakeItem() { // 建立item元素, 這裡以Label元素呈現item
        Label label = new Label();
        label.style.fontSize = 50;
        label.style.unityTextAlign = TextAnchor.MiddleLeft;
        return label;
    }

    private void BindItem(VisualElement visualElement, int index) { // 繫結item
        Label label = visualElement as Label;
        label.text = itemsTitle[index];
    }

    private void OnSelectionChange(IEnumerable<object> objs) { // 選中事件回撥
        foreach (object item in objs) {
            int data = (int) item;
            Debug.Log(data);
        }
    }
}

​ 執行後,點選 Second,顯示如下。

img

​ 列印日誌如下。

img

5 GroupBox(分組盒子)

​ GroupBox 是一個邏輯分組容器,官方介紹見→UXML element GroupBox

1)屬性介紹

img

  • Text: 分組標題。

2)GroupBox 的使用

​ GroupBoxDemo.cs

using UnityEngine;
using UnityEngine.UIElements;

public class GroupBoxDemo : MonoBehaviour {
    private VisualElement root; // 根容器
    private GroupBox groupBox; // 分組盒子
    private string[] choiceLabel = new string[] {"First", "Second", "Third", "Fourth"}; // choice的標籤

    private void Awake() {
        root = GetComponent<UIDocument>().rootVisualElement;
        groupBox = root.Q<GroupBox>();
        groupBox.text = "GroupBoxDemo";
        groupBox.style.fontSize = 50;
        root.Add(groupBox);
        for (int i = 0; i < choiceLabel.Length; i++) {
            AddChoice(i);
        }
    }

    private void AddChoice(int index) { // 新增單選項
        RadioButton choice = new RadioButton();
        choice.text = choiceLabel[index];
        choice.style.fontSize = 50;
        VisualElement ve = choice.Query<VisualElement>().AtIndex(2);
        ve.style.marginRight = 10;
        choice.RegisterValueChangedCallback(e => OnValueChanged(index, e));
        groupBox.Add(choice);
    }

    private void OnValueChanged(int index, ChangeEvent<bool> e) { // 選項變化回撥函式
        Debug.Log("index=" + index + ", previousValue=" + e.previousValue + ", newValue=" + e.newValue);
    }
}

​ 執行後,點選 Second,顯示如下。

img

​ 列印日誌如下。

img

​ 宣告:本文轉自【Unity3D】UI Toolkit容器

相關文章