UI コードからイベントロジックを分離するには、マニピュレーターを使用してイベントを処理します。マニピュレーターは、UI 要素とのユーザーインタラクションを処理するステートマシンです。イベントのコールバックを格納、登録、および登録解除します。マニピュレーターによってユーザーインタラクションの設定が効率化されるため、コールバックを 1 つずつ処理する必要はありません。イベントを処理するには、UI Toolkit がサポートするマニピュレーターの 1 つを使用または継承します。
マニピュレーターを作成して使用するには、以下の手順を行います。
以下の表は、サポートされているマニピュレータークラスの一覧です。
| マニピュレーター | 継承元 | 説明 |
|---|---|---|
Manipulator |
指定されたすべてのマニピュレーターの基本クラス。 | |
KeyboardNavigationManipulator |
Manipulator |
デバイス固有の入力イベントをキーボードによる高次のナビゲーション操作に変換する処理を行います。 |
MouseManipulator |
Manipulator |
マウスの入力を処理します。アクティベーションフィルターのリストを保持します。 |
ContextualMenuManipulator |
MouseManipulator |
ユーザーがマウスの右ボタンをクリックした場合、またはキーボードのキーを押した場合にコンテキストメニューを表示します。 |
PointerManipulator |
MouseManipulator |
ポインター入力を処理します。アクティベーションフィルターのリストを保持します。 |
Clickable |
PointerManipulator |
要素上のマウスイベントを追跡し、同じ要素上でポインターの押下とリリースの両方のクリックが発生したときに識別します。 |
以下の例は、マニピュレーターを使用してイベントを処理する方法を示しています。行う処理の内容を以下に示します。
PointerManipulators クラスからマニピュレーターを継承します。activators リストを使用して、マニピュレーターをアクティベートする条件を指定します。例えば、ユーザーがマウスの左ボタンをクリックしたときにマニピュレーターをアクティベートするには、ManipulatorActivationFilter を activators リストに追加して button フィールドを MouseButton.LeftMouse に設定します。target プロパティを使用して、マニピュレーターがアタッチされている要素にアクセスします。RegisterCallbacksOnTarget メソッドと UnregisterCallbacksFromTarget メソッドをオーバーライドして、イベントコールバックを登録および登録解除します。以下の例では、クリックアンドドラッグされた際に要素を移動するマニピュレーターを作成します。
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();
}
}
以下の例では、要素がドラッグされた際に要素のサイズを変更するマニピュレーターを作成します。
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();
}
}
要素にマニピュレーターを追加するには、AddManipulator メソッドを使用します。要素からマニピュレーターを削除するには、RemoveManipulator メソッドを使用します。
以下の例では、VisualElement に対して ExampleDragger を追加および削除します。
// Create a VisualElement.
var myElement = new VisualElement();
// Add manipulators to the VisualElement.
myElement.AddManipulator(new ExampleDragger());
// Remove manipulators from the VisualElement.
myElement.RemoveManipulator<ExampleDragger>();
以下の例では、ExampleResizer を VisualElement に追加します。
var box = new VisualElement()
{
style =
{
left = 100,
top = 100,
width = 100,
height = 100,
backgroundColor = Color.red
},
pickingMode = PickingMode.Position,
};
box.AddManipulator(new ExampleResizer());