Version: 2021.3
言語: 日本語
Dispatching events
Synthesizing events

Handle events

UI Toolkit のイベントは、HTML イベント に似ています。イベントが発生すると、ビジュアル要素ツリーの伝搬経路に沿って送信されます。イベントは対象となるビジュアル要素だけでなく、伝搬経路内のすべての要素に送信されます。

イベント処理の流れは以下の通りです。

  1. ルート要素からイベントターゲットの親までの要素にイベントコールバックを実行する。これはディスパッチプロセスの 下降段階 です。
  2. イベントターゲットでイベントコールバックを実行します。これはディスパッチ処理の ターゲット段階 です。
  3. イベントターゲットで ExecuteDefaultActionAtTarget() を呼び出します。
  4. イベントターゲットの親からルートまでの要素のイベントコールバックを実行します。これはディスパッチプロセスの 上昇段階 です。
  5. ExecuteDefaultAction() をイベントターゲット上で呼び出します。

イベントが伝搬経路を移動すると、Event.currentTarget プロパティは、現在そのイベントを処理する要素に更新されます。イベントコールバック関数内では、以下の通りです。

  • Event.currentTarget は、コールバックが登録されるビジュアル要素です。
  • Event.target は、元のイベントが発生するビジュアル要素です。

詳しくは、イベントのディスパッチ を参照してください。

Register an event callback

イベントコールバックを登録すると、テキストラベル上でマウスをクリックしたときの動作など、既存クラスの個々のインスタンスの動作をカスタマイズできます。

伝搬経路上の各要素 (ターゲットを除く) は、イベントを 2 回受け取ることができます。

  • 降下段階で 1 度。
  • 上昇段階で 1 度

デフォルトでは、登録されたコールバックは、ターゲットフェーズとバブルアップフェーズの間に実行されます。このデフォルトの動作により、親要素が子要素の後に反応するようになります。例えば、親要素が子要素より先に反応するようにしたい場合は、 TrickleDown.TrickleDown オプションでコールバックを登録します。

// 降下段階のコールバックを登録
myElement.RegisterCallback<MouseDownEvent>(MyCallback, TrickleDown.TrickleDown);

これは、ディスパッチャーに、ターゲット段階と降下段階でコールバックを実行するように通知します。

カスタム動作を特定のビジュアル要素に加えるには、イベントのコールバックを登録する必要があります。例えば、以下のコードは MouseDownEvent のコールバックを登録します。

// マウスダウンイベントのコールバックの登録
myElement.RegisterCallback<MouseDownEvent>(MyCallback);

コールバックの署名は以下のようになります。

void MyCallback(MouseDownEvent evt) { /* ... */ }

1 つのイベントに対して複数のコールバックを登録することができます。同じコールバック関数を登録できるのは、同じイベントと同じプロパゲーションフェーズに 1 度だけです。VisualElement からコールバックを削除するには、myElement.UnregisterCallback() メソッドを呼び出します。

Send custom data to an event callback

イベントのコールバックと一緒にカスタムデータを送ることができます。カスタムデータを添付するには、呼び出しを拡張してコールバックを登録する必要があります。

以下のコードでは、MouseDownEvent のコールバックを登録し、カスタムデータをコールバック関数に送信しています。

// ユーザーデータをコールバックとともに送信
myElement.RegisterCallback<MouseDownEvent, MyType>(MyCallbackWithData, myData);

コールバック関数は、この署名を返します。

void MyCallbackWithData(MouseDownEvent evt, MyType data) { /* ... */ }

Handle input events for a control

You can use an event handler or use a manipulator to handle input events.

Capture the pointer

When you handle pointer input, you might want the control to capture a pointer. When a visual element captures a pointer, Unity sends all the events associated with the pointer to the visual element regardless of whether the pointer hovers over the visual element. For example, if you create a control that receives drag events and captures the pointer, the control still receives drag events regardless of the pointer location.

To capture a pointer, use capture events. See Create a drag-and-drop UI inside a custom Editor window for an example.

Use a manipulator to handle events

If you want to separate your event logic from your UI code, use a manipulator to handle events. A manipulator is a dedicated class that stores, registers, and unregisters event callbacks. You can use or inherit from one of the manipulators that UI Toolkit supports to handle events.

UI Toolkit supports the following manipulators:

Manipulator Inherits from 説明
Manipulator Base class for all provided manipulators.
KeyboardNavigationManipulator Manipulator Handles translation of device-specific input events to higher-level navigation operations with a keyboard.
MouseManipulator Manipulator Handles mouse input. Has a list of activation filters.
ContextualMenuManipulator MouseManipulator Displays a contextual menu when the user clicks the right mouse button or presses the menu key on the keyboard.
PointerManipulator MouseManipulator Handles pointer input. Has a list of activation filters.
Clickable PointerManipulator Tracks mouse events on an element and callbacks when a user clicks a mouse button while the pointer hovers over an element.

Respond to events with custom controls

カスタムコントロールを実装している場合、UI Toolkit のイベントに 2 つの方法で応答することができます。

  • イベントコールバックの登録
  • デフォルトアクションの実装

イベントに対してどのように対応するかは、状況によって異なります。

コールバックとデフォルトアクションの違いは以下の通りです。

  • コールバックはクラスのインスタンスに登録する必要があります。デフォルトアクションは、クラスの仮想関数として実行されます。
  • コールバックは、伝搬経路上のすべてのビジュアル要素に対して実行されます。デフォルトのアクションは、イベントターゲットに対してのみ実行されます。
  • コールバックは、イベントに反応すべきかどうかを判断するために、追加確認を行う場合があります。例えば、マウスのクリックを処理するコールバックは、その要素がイベントのターゲットであるかどうかを確認する場合があります。デフォルトのアクションはこの手順を省略できます。
  • デフォルトアクションは伝搬段階でコールバックレジストリの検索を必要としないため、パフォーマンス面で若干有利です。

Implement a default action

デフォルトアクションは、クラスのすべてのインスタンスに適用されます。デフォルトアクションを実装するクラスは、そのインスタンスにコールバックを登録することもできます。

クラスにデフォルトのアクションを実装する場合、VisualElement の新しいサブクラスを派生させ、ExecuteDefaultActionAtTarget() メソッドか ExecuteDefaultAction() メソッドのいずれか、または両方を実装する必要があります。

デフォルトアクションは、ビジュアル要素のサブクラスのインスタンスがイベントを受け取ったときに、各インスタンス上で実行されます。デフォルトアクションをカスタマイズするには、以下の例のように、 ExecuteDefaultActionAtTarget()ExecuteDefaultAction() をオーバーライドします。

override void ExecuteDefaultActionAtTarget(EventBase evt)
{
    // 基礎関数を呼び出す
    base.ExecuteDefaultActionAtTarget(evt);

    if (evt.GetEventTypeId() == MouseDownEvent.TypeId())
    {
        // ...
    }
    else if (evt.GetEventTypeId() == MouseUpEvent.TypeId())
    {
        // ...
    }
    // イベントタイプを追加
}

ExecuteDefaultAction() にデフォルトアクションを実装すると、デフォルトのアクションの実行を停止または防止できます。

ターゲットのデフォルトアクションを親のコールバックの前に実行したい場合は、デフォルトアクションを ExecuteDefaultActionAtTarget() に実装します。

デフォルトアクションは、あるタイプの要素がイベントを受け取ったときの動作と考える必要があります。例えば、チェックボックスは、クリックイベントに反応して、その状態を切り替えます。これを実行するには、すべてのチェックボックスにコールバックを登録するのではなく、デフォルトアクションの仮想関数をオーバーライドします。

カスタム制御の実践例

The following are best practices for custom controls.

Implement behaviors

要素の動作をデフォルトの動作で実装する必要があります。インスタンスに接続されたコールバックで PreventDefault() を呼び出すことで、要素のデフォルトの動作をキャンセルすることができます。

動作をデフォルトアクションとして実装することによるその他の利点は以下の通りです。

  • デフォルトアクションが、コールバックレジストリのルックアップを必要としません。
  • コールバックのないインスタンスは伝搬プロセスに入りません。

柔軟性を高めるために、イベントのディスパッチ処理中にイベントターゲットのデフォルトのアクションを 2 か所で実行できます。

  1. 下降と上昇の伝播段階の間で、ターゲットコールバックの実行直後に、ExecuteDefaultActionsAtTarget() をオーバーライドします。
  2. イベントのディスパッチプロセスの最後に、ExecuteDefaultActions() をオーバーライドします。

クラスのデフォルトアクション

可能であれば ExecuteDefaultActions() にクラスのデフォルトアクションを実装してください。これにより、クラスをオーバーライドするためのオプションが増えます。PreventDefault() を呼び出して、イベント伝播プロセスの降下段階または上昇段階でクラスをオーバーライドすることができます。

イベントが親要素に伝搬してはいけない場合は、デフォルトアクション中にイベントの伝搬を停止する必要があります。例えば、テキストフィールドは KeyDownEvent を受け取って、その値を変更します。例えば、Delete キーでコンテンツを削除するように。このイベントは、親のビジュアル要素に伝播してはいけません。ExecuteDefaultActionsAtTarget() を使ってデフォルトアクションを実装し、StopPropagation() を呼び出して上昇段階でイベントが処理されないようにします。

デフォルトアクションは、イベントターゲットに対してのみ実行されます。クラスが子要素や親要素を対象としたイベントに反応するには、降下または上昇の伝搬段階で、イベントを受け取るコールバックを登録する必要があります。パフォーマンスを向上させるために、クラスにコールバックを登録することは避けてください。

Stop event propagation and cancel default actions

コールバックやデフォルトアクションの中でイベントを処理する場合、イベントの伝搬やデフォルトアクションの実行を停止することができます。例えば、親パネルは降下段階で伝搬を停止し、子パネルがイベントを受け取らないようにすることができます。

EventBase.PreDispatch()EventBase.PostDispatch() メソッドの実行は、イベントクラスの内部で防ぐことはできません。

以下のメソッドは、イベント伝播とデフォルトアクションに影響します。

  • StopImmediatePropagation(): Stops the event propagation process immediately, so no other callbacks execute for the event. However, the ExecuteDefaultActionAtTarget() and ExecuteDefaultAction() default actions still execute.
  • StopPropagation(): Stops the event propagation process after the last callback on the current element. This ensures that all callbacks execute on the current element, but no further elements react to the event. The ExecuteDefaultActionAtTarget() and ExecuteDefaultAction() default actions still execute.
  • PreventDefaultAction(): Prevents the event propagation process from calling the ExecuteDefaultActionAtTarget() and ExecuteDefaultAction() default actions. PreventDefaultAction() doesn’t prevent the execution of other callbacks and doesn’t effective the ExecuteDefaultActionAtTarget() action during the bubble-up phase.
Dispatching events
Synthesizing events
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961