Manipulators
是處理使用者與UI Element交互的State machine
,它被用來儲存,註冊,取消註冊event callbacks
。
建立與使用Manipulators
你不需要自己撰寫管理callback的class,你只需要要繼承UI Toolkit提供的manipulators class就可以使用它們來管理callback與event,步驟如下:
- 建立一個class,這個class封裝了針對特定使用者互動所需的事件處理邏輯,並繼承了UI Toolkit提供的manipulators class。
- 在這個class中,實作方法(method)來回應相關的互動,例如滑鼠點擊或拖曳。這些方法捕獲並處理必要的資訊以執行這個互動行為(behavior)。
- 當你完成設計這個class之後,你就可以實體化它並將其附加到目標(target) UI Element上。這個附加使這個Manipulator class可以攔截和管理指定的事件,並協調使用者互動,同時與你的UI程式碼保持清晰的分離。
- 在Visual Element上使用
AddManipulator
將建立的Manipulator加入到這個Element
- 在Visual Element上使用
RemoveManipulator
為這個Element移除指定的的Manipulator
例子
以下範例將示範
- 如何一個繼承
PointerManipulator
,來處理滑鼠輸入,
- 並使用
activators
list屬性來設定可以啟用這個manipulator的條件,
- 例如:當使用者點擊滑鼠左鍵時,啟用這個manipulator
- 要做到這個,你只要實體化一個
ManipulatorActivationFilter
,將其button屬性設為MouseButton.LeftMouse
並加入到activators
list即可
- 使用
target
屬性來存取附加這個manipulator的element,
- Override
RegisterCallbacksOnTarget
與UnregisterCallbacksFromTarget
方法用以註冊和取消註冊event callbacks。
建立一個可以讓你拖動element的manipulator
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 66 67 68 69 70 71 72 73 74 75 76 77
| using UnityEngine; using UnityEngine.UIElements;
public class ExampleDragger : PointerManipulator { private Vector3 m_Start; protected bool m_Active; private int m_PointerId; private Vector2 m_StartSize;
public ExampleDragger() { m_PointerId = -1; activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse }); m_Active = false; }
protected override void RegisterCallbacksOnTarget() { target.RegisterCallback<PointerDownEvent>(OnPointerDown); target.RegisterCallback<PointerMoveEvent>(OnPointerMove); target.RegisterCallback<PointerUpEvent>(OnPointerUp); }
protected override void UnregisterCallbacksFromTarget() { target.UnregisterCallback<PointerDownEvent>(OnPointerDown); target.UnregisterCallback<PointerMoveEvent>(OnPointerMove); target.UnregisterCallback<PointerUpEvent>(OnPointerUp); }
protected void OnPointerDown(PointerDownEvent e) { if (m_Active) { e.StopImmediatePropagation(); return; }
if (CanStartManipulation(e)) { m_Start = e.localPosition; m_PointerId = e.pointerId;
m_Active = true; target.CapturePointer(m_PointerId); e.StopPropagation(); } }
protected void OnPointerMove(PointerMoveEvent e) { if (!m_Active || !target.HasPointerCapture(m_PointerId)) return;
Vector2 diff = e.localPosition - m_Start;
target.style.top = target.layout.y + diff.y; target.style.left = target.layout.x + diff.x;
e.StopPropagation(); }
protected void OnPointerUp(PointerUpEvent e) { if (!m_Active || !target.HasPointerCapture(m_PointerId) || !CanStopManipulation(e)) return;
m_Active = false; target.ReleaseMouse(); e.StopPropagation(); } }
|
建立一個可以當拖動時,改變element大小的manipulator
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 66 67 68 69 70 71 72 73
| using UnityEngine; using UnityEngine.UIElements;
public class ExampleResizer : PointerManipulator { private Vector3 m_Start; protected bool m_Active; private int m_PointerId; private Vector2 m_StartSize; public ExampleResizer() { m_PointerId = -1; activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse }); m_Active = false; }
protected override void RegisterCallbacksOnTarget() { target.RegisterCallback<PointerDownEvent>(OnPointerDown); target.RegisterCallback<PointerMoveEvent>(OnPointerMove); target.RegisterCallback<PointerUpEvent>(OnPointerUp); }
protected override void UnregisterCallbacksFromTarget() { target.UnregisterCallback<PointerDownEvent>(OnPointerDown); target.UnregisterCallback<PointerMoveEvent>(OnPointerMove); target.UnregisterCallback<PointerUpEvent>(OnPointerUp); }
protected void OnPointerDown(PointerDownEvent e) { if (m_Active) { e.StopImmediatePropagation(); return; }
if (CanStartManipulation(e)) { m_Start = e.localPosition; m_StartSize = target.layout.size; m_PointerId = e.pointerId; m_Active = true; target.CapturePointer(m_PointerId); e.StopPropagation(); } }
protected void OnPointerMove(PointerMoveEvent e) { if (!m_Active || !target.HasPointerCapture(m_PointerId)) return;
Vector2 diff = e.localPosition - m_Start;
target.style.height = m_StartSize.y + diff.y; target.style.width = m_StartSize.x + diff.x;
e.StopPropagation(); }
protected void OnPointerUp(PointerUpEvent e) { if (!m_Active || !target.HasPointerCapture(m_PointerId) || !CanStopManipulation(e)) return;
m_Active = false; target.ReleasePointer(m_PointerId); m_PointerId = -1; e.StopPropagation(); } }
|
加入manipulator
1 2 3 4
| var myElement = new VisualElement();
myElement.AddManipulator(new ExampleDragger());
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var box = new VisualElement() { style = { left = 100, top = 100, width = 100, height = 100, backgroundColor = Color.red }, pickingMode = PickingMode.Position, };
box.AddManipulator(new ExampleResizer());
|
移除manipulator
1 2
| myElement.RemoveManipulator<ExampleDragger>();
|