事件捕捉(Capture events)

事件捕捉(Capture events)通知你滑鼠捕捉狀態(mouse capture state)的變化,在UI Toolkit中的事件有兩捕捉種類型:

  1. 滑鼠捕捉事件(Mouse capture events)
  2. 指標捕捉事件(Pointer capture events)

當一個element捕捉了滑鼠或指標,它是唯一接收來自點擊裝置(Pointing device,如滑鼠)事件的element,直到該裝置釋放或失去捕捉為止。例如:假設你使用滑鼠點擊了一個文字框(text box),這個文字框會捕捉這個滑鼠,此時滑鼠仍然可以移動,但是它不會觸發文字框之外的事件;只要這個文字框正在捕捉你的滑鼠,那麼它就不會觸發其他事件。當你在文字框之外按下滑鼠上的按鈕時,文字框會釋放其滑鼠捕捉。

捕捉滑鼠(Mouse capture)

滑鼠捕捉事件(Mouse capture events)是實體滑鼠或是模擬滑鼠的虛擬滑鼠上的事件。捕捉到滑鼠時,也會產生一個滑鼠指標的PointerCaptureEvent。當一個element釋放捕捉滑鼠時,會觸發相應的MouseCaptureOutEvent

注意:不會發生同時有兩個elements同時捕捉滑鼠的情況,如果另外一個Visual Element觸發了MouseCaptureEvent那麼原先捕捉滑鼠的Element就會釋滑鼠並收到一個MouseCaptureOutEvent

捕捉指標(Pointer capture)

在UI Toolkit中,指標事件優先於滑鼠事件。如果指標的類型是滑鼠的話,在捕捉到指標事件時也會觸發滑鼠事件。

Event 描述 Trickles down Bubbles up Cancellable
MouseCaptureEvent 當某個Element被滑鼠捕捉時會發送這個事件,此時target為這個Element
MouseCaptureOutEvent 當某個Element捕捉的滑鼠被釋放或是某些其他原因是放時,會發送這個事件,此時target為這個失去滑鼠捕捉的Element
PointerCaptureEvent 當某個Element捕捉指標時會發送這個事件,此時target為這個Element
PointerCaptureOutEvent 當某個Element捕捉的指標被釋放時,會發送這個事件,此時target為這個失去指標捕捉的Element
例子

以下例子為示範捕捉與釋放的行為

  1. Assets > Scripts > Editor 下建立一個 C# Script CaptureEventsTestWindow.cs

  2. 將以下程式碼複製到剛剛建立的C# Script中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    using UnityEditor;
    using UnityEngine;
    using UnityEngine.UIElements;

    public class CaptureEventsTestWindow : EditorWindow
    {
    // 這個Attributes會在 Windows -> UI Tollkit 下加入一個 Capture Events Test Window
    [MenuItem("Window/UI Toolkit/Capture Events Test Window")]
    public static void ShowExample()
    {
    var wnd = GetWindow<CaptureEventsTestWindow>();
    wnd.titleContent = new GUIContent("Capture Events Test Window");
    }

    private bool m_IsCapturing = false;

    public void CreateGUI()
    {
    for (int i = 0; i < 4; i++)
    {
    // 建立一個 Label 的Visual Element
    Label clickableLabel = new Label($"Label {i} - Click Me!");
    // 為這個Label Element註冊 MouseDownEvent
    clickableLabel.RegisterCallback<MouseDownEvent>((evt) => {
    // 這個匿名Callback會在Console中印出 Clicked on label *** 的字串
    Debug.Log($"Clicked on label '{(evt.target as Label).text}'");
    });
    rootVisualElement.Add(clickableLabel);
    }

    // 建立一個 Label 的Visual Element
    Label capturingLabel = new Label("Click here to capture mouse");
    // 為這個Label Element註冊 MouseDownEvent
    capturingLabel.RegisterCallback<MouseDownEvent>((evt) =>
    {
    if (!m_IsCapturing)
    {
    capturingLabel.text = "Click here to release mouse";
    // 捕捉滑鼠
    MouseCaptureController.CaptureMouse(capturingLabel);
    m_IsCapturing = true;
    }
    else
    {
    capturingLabel.text = "Click here to capture mouse";
    // 釋放捕捉
    MouseCaptureController.ReleaseMouse(capturingLabel);
    m_IsCapturing = false;
    }
    });
    rootVisualElement.Add(capturingLabel);

    // 註冊捕捉滑鼠事件
    rootVisualElement.RegisterCallback<MouseCaptureEvent>((evt) =>
    {
    Debug.Log("Mouse captured");
    });

    // 註冊滑鼠釋放捕捉事件
    rootVisualElement.RegisterCallback<MouseCaptureOutEvent>((evt) =>
    {
    Debug.Log("Mouse captured released");
    });
    }
    }
  3. 在Unity編輯器中找到 Window > UI Toolkit > Capture Events Test Window

  4. 點擊Test Window上面的Label來觀看結果

Reference: https://docs.unity3d.com/Manual/UIE-Change-Events.html

評論