Version: Unity 6.0 (6000.0)
言語 : 日本語
カスタムコントロールによるイベントへの応答
イベントの統合と送信

マニピュレーター

UI コードからイベントロジックを分離するには、マニピュレーターを使用してイベントを処理します。マニピュレーターは、UI 要素とのユーザーインタラクションを処理するステートマシンです。イベントのコールバックを格納、登録、および登録解除します。マニピュレーターによってユーザーインタラクションの設定が効率化されるため、コールバックを 1 つずつ処理する必要はありません。イベントを処理するには、UI Toolkit がサポートするマニピュレーターの 1 つを使用または継承します。

マニピュレーターを作成して使用するには、以下の手順を行います。

  1. UI Toolkit でサポートされているマニピュレータークラスを継承する専用クラスを定義します。このクラスでは、管理する必要がある特定のユーザーインタラクションに合わせてイベント処理ロジックがカプセル化されます。
  2. クラス内で、マウスのクリックやドラッグなど、関連する操作に応答するメソッドを実装します。これらのメソッドは、目的とする動作を実行するために必要な情報をキャプチャおよび処理します。
  3. マニピュレータークラスの設計が完了したら、そのクラスをインスタンス化し、ターゲット UI 要素にアタッチします。このアタッチメントを使用すると、マニピュレーターは指定されたイベントをインターセプトして管理し、UI コードから明確に分離された状態を維持しながらユーザーインタラクションをオーケストレートできます。

サポートされているマニピュレーター

以下の表は、サポートされているマニピュレータークラスの一覧です。

マニピュレーター 継承元 説明
Manipulator 指定されたすべてのマニピュレーターの基本クラス。
KeyboardNavigationManipulator Manipulator デバイス固有の入力イベントをキーボードによる高次のナビゲーション操作に変換する処理を行います。
MouseManipulator Manipulator マウスの入力を処理します。アクティベーションフィルターのリストを保持します。
ContextualMenuManipulator MouseManipulator ユーザーがマウスの右ボタンをクリックした場合、またはキーボードのキーを押した場合にコンテキストメニューを表示します。
PointerManipulator MouseManipulator ポインター入力を処理します。アクティベーションフィルターのリストを保持します。
Clickable PointerManipulator 要素上のマウスイベントを追跡し、同じ要素上でポインターの押下とリリースの両方のクリックが発生したときに識別します。

以下の例は、マニピュレーターを使用してイベントを処理する方法を示しています。行う処理の内容を以下に示します。

  • マウス入力を処理する PointerManipulators クラスからマニピュレーターを継承します。
  • activators リストを使用して、マニピュレーターをアクティベートする条件を指定します。例えば、ユーザーがマウスの左ボタンをクリックしたときにマニピュレーターをアクティベートするには、ManipulatorActivationFilteractivators リストに追加して button フィールドを MouseButton.LeftMouse に設定します。
  • target プロパティを使用して、マニピュレーターがアタッチされている要素にアクセスします。
  • RegisterCallbacksOnTarget メソッドと UnregisterCallbacksFromTarget メソッドをオーバーライドして、イベントコールバックを登録および登録解除します。

ExampleDragger マニピュレーターの作成

以下の例では、クリックアンドドラッグされた際に要素を移動するマニピュレーターを作成します。

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

ExampleResizer マニピュレーターの作成

以下の例では、要素がドラッグされた際に要素のサイズを変更するマニピュレーターを作成します。

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

以下の例では、ExampleResizerVisualElement に追加します。

var box = new VisualElement()
{
    style =
    {
        left = 100,
        top = 100,
        width = 100,
        height = 100,
        backgroundColor = Color.red
    },
    pickingMode = PickingMode.Position,
};

box.AddManipulator(new ExampleResizer());

追加リソース

カスタムコントロールによるイベントへの応答
イベントの統合と送信