事件捕捉(Capture events)
事件捕捉(Capture events)通知你滑鼠捕捉狀態(mouse capture state)的變化,在UI Toolkit中的事件有兩捕捉種類型:
- 滑鼠捕捉事件(Mouse capture events)
- 指標捕捉事件(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 |
✔ | ✔ |
例子
以下例子為示範捕捉與釋放的行為
在
Assets
>Scripts
>Editor
下建立一個 C# ScriptCaptureEventsTestWindow.cs
將以下程式碼複製到剛剛建立的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
65using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class CaptureEventsTestWindow : EditorWindow
{
// 這個Attributes會在 Windows -> UI Tollkit 下加入一個 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");
});
}
}在Unity編輯器中找到
Window
>UI Toolkit
>Capture Events Test Window
點擊Test Window上面的Label來觀看結果
Reference: https://docs.unity3d.com/Manual/UIE-Change-Events.html