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>();
 
  |