UI Toolkit のイベントは、HTML イベント に似ています。イベントが発生すると、ビジュアル要素ツリーの伝搬経路に沿って送信されます。イベントは対象となるビジュアル要素だけでなく、伝搬経路内のすべての要素に送信されます。
イベント処理の流れは以下の通りです。
ExecuteDefaultActionAtTarget()
を呼び出します。ExecuteDefaultAction()
をイベントターゲット上で呼び出します。イベントが伝搬経路を移動すると、Event.currentTarget
プロパティは、現在そのイベントを処理する要素に更新されます。イベントコールバック関数内では、以下の通りです。
Event.currentTarget
は、コールバックが登録されるビジュアル要素です。Event.target
は、元のイベントが発生するビジュアル要素です。詳しくは、イベントのディスパッチ を参照してください。
イベントコールバックを登録すると、テキストラベル上でマウスをクリックしたときの動作など、既存クラスの個々のインスタンスの動作をカスタマイズできます。
伝搬経路上の各要素 (ターゲットを除く) は、イベントを 2 回受け取ることができます。
デフォルトでは、登録されたコールバックは、ターゲットフェーズとバブルアップフェーズの間に実行されます。このデフォルトの動作により、親要素が子要素の後に反応するようになります。例えば、親要素が子要素より先に反応するようにしたい場合は、 TrickleDown.TrickleDown
オプションでコールバックを登録します。
// 降下段階のコールバックを登録
myElement.RegisterCallback<MouseDownEvent>(MyCallback, TrickleDown.TrickleDown);
これは、ディスパッチャーに、ターゲット段階と降下段階でコールバックを実行するように通知します。
カスタム動作を特定のビジュアル要素に加えるには、イベントのコールバックを登録する必要があります。例えば、以下のコードは MouseDownEvent
のコールバックを登録します。
// マウスダウンイベントのコールバックの登録
myElement.RegisterCallback<MouseDownEvent>(MyCallback);
コールバックの署名は以下のようになります。
void MyCallback(MouseDownEvent evt) { /* ... */ }
1 つのイベントに対して複数のコールバックを登録することができます。同じコールバック関数を登録できるのは、同じイベントと同じプロパゲーションフェーズに 1 度だけです。VisualElement
からコールバックを削除するには、myElement.UnregisterCallback()
メソッドを呼び出します。
イベントのコールバックと一緒にカスタムデータを送ることができます。カスタムデータを添付するには、呼び出しを拡張してコールバックを登録する必要があります。
以下のコードでは、MouseDownEvent
のコールバックを登録し、カスタムデータをコールバック関数に送信しています。
// ユーザーデータをコールバックとともに送信
myElement.RegisterCallback<MouseDownEvent, MyType>(MyCallbackWithData, myData);
コールバック関数は、この署名を返します。
void MyCallbackWithData(MouseDownEvent evt, MyType data) { /* ... */ }
You can use an event handler or use a manipulator to handle input events.
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.
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. |
カスタムコントロールを実装している場合、UI Toolkit のイベントに 2 つの方法で応答することができます。
イベントに対してどのように対応するかは、状況によって異なります。
コールバックとデフォルトアクションの違いは以下の通りです。
デフォルトアクションは、クラスのすべてのインスタンスに適用されます。デフォルトアクションを実装するクラスは、そのインスタンスにコールバックを登録することもできます。
クラスにデフォルトのアクションを実装する場合、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.
要素の動作をデフォルトの動作で実装する必要があります。インスタンスに接続されたコールバックで PreventDefault()
を呼び出すことで、要素のデフォルトの動作をキャンセルすることができます。
動作をデフォルトアクションとして実装することによるその他の利点は以下の通りです。
柔軟性を高めるために、イベントのディスパッチ処理中にイベントターゲットのデフォルトのアクションを 2 か所で実行できます。
ExecuteDefaultActionsAtTarget()
をオーバーライドします。ExecuteDefaultActions()
をオーバーライドします。可能であれば ExecuteDefaultActions()
にクラスのデフォルトアクションを実装してください。これにより、クラスをオーバーライドするためのオプションが増えます。PreventDefault()
を呼び出して、イベント伝播プロセスの降下段階または上昇段階でクラスをオーバーライドすることができます。
イベントが親要素に伝搬してはいけない場合は、デフォルトアクション中にイベントの伝搬を停止する必要があります。例えば、テキストフィールドは KeyDownEvent
を受け取って、その値を変更します。例えば、Delete
キーでコンテンツを削除するように。このイベントは、親のビジュアル要素に伝播してはいけません。ExecuteDefaultActionsAtTarget()
を使ってデフォルトアクションを実装し、StopPropagation()
を呼び出して上昇段階でイベントが処理されないようにします。
デフォルトアクションは、イベントターゲットに対してのみ実行されます。クラスが子要素や親要素を対象としたイベントに反応するには、降下または上昇の伝搬段階で、イベントを受け取るコールバックを登録する必要があります。パフォーマンスを向上させるために、クラスにコールバックを登録することは避けてください。
コールバックやデフォルトアクションの中でイベントを処理する場合、イベントの伝搬やデフォルトアクションの実行を停止することができます。例えば、親パネルは降下段階で伝搬を停止し、子パネルがイベントを受け取らないようにすることができます。
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.