Events in UI Toolkit are similar to HTML events. When an event occurs, it’s sent to the target visual element and to all elements within the propagation path in the visual element tree.
이벤트 처리 시퀀스는 다음과 같습니다.
ExecuteDefaultActionAtTarget()
을 호출합니다.ExecuteDefaultAction()
을 호출합니다.이벤트가 전파 경로를 따라 이동하면 Event.currentTarget
프로퍼티가 현재 이벤트를 처리하는 요소에 업데이트됩니다. 이벤트 콜백 함수 내에서:
Event.currentTarget
은 콜백이 등록되는 시각적 요소입니다.Event.target
은 원본 이벤트가 발생하는 시각적 요소입니다.자세한 내용은 디스패치 이벤트를 참조하십시오.
You can register an event callback to customize the behavior of an individual instance of an existing class, such as reacting to a mouse click on a text label.
전파 경로를 따라 전달되는 각 요소(타겟 제외)는 다음과 같이 하나의 이벤트를 두 번 수신할 수 있습니다.
By default, a registered callback executes during the target phase and the bubble-up phase. This default behavior ensures that a parent element reacts after its child element.
On the other hand, if you want a parent element to react before its child, register your callback with the TrickleDown.TrickleDown
option:
using UnityEngine;
using UnityEngine.UIElements;
...
VisualElement myElement = new VisualElement();
// Register a callback for the trickle-down phase.
myElement.RegisterCallback<MouseDownEvent>(MyCallback, TrickleDown.TrickleDown);
...
이는 디스패처에 타겟 단계와 트리클다운 단계에서 콜백을 실행하라고 알립니다.
To add a custom behavior to a specific visual element, register an event callback on that element.
The following example registers a callback for the MouseDownEvent
:
// Register a callback on a mouse down event
myElement.RegisterCallback<MouseDownEvent>(MyCallback);
The signature for the callback function looks like this:
void MyCallback(MouseDownEvent evt) { /* ... */ }
You can register multiple callbacks for an event. However, you can only register the same callback function on the same event and propagation phase once.
To remove a callback from a VisualElement
, call the myElement.UnregisterCallback()
method.
콜백과 함께 커스텀 데이터를 이벤트로 전송할 수 있습니다. 커스텀 데이터를 부착하려면 호출을 연장하여 콜백을 등록해야 합니다.
The following example registers a callback for the MouseDownEvent
and sends custom data to the callback function:
// Send user data along to the callback
myElement.RegisterCallback<MouseDownEvent, MyType>(MyCallbackWithData, myData);
The signature for the callback function looks like this:
void MyCallbackWithData(MouseDownEvent evt, MyType data) { /* ... */ }
UI controls can use the value
property to hold data for their internal state. For example:
Toggle
holds a Boolean value that changes when the Toggle
is turned on or off.IntegerField
holds an integer that holds the field’s value.You can get the value of the control by the following:
Get the value from the control directly: int val = myIntegerField.value;
.
Listen to a ChangeEvent
sent by the control and process the change when it happens. You must register your callback to the event like this:
//RegisterValueChangedCallback is a shortcut for RegisterCallback<ChangeEvent>.
//It constrains the right type of T for any VisualElement that implements an
//INotifyValueChange interface.
myIntegerField.RegisterValueChangedCallback(OnIntegerFieldChange);
The signature for the callback function looks like this:
void OnIntegerFieldChange(ChangeEvent<int> evt) { /* ... */ }
You can change the value of a control by the following:
value
variable: myControl.value = myNewValue;
. This will trigger a new ChangeEvent
.myControl.SetValueWithoutNotify(myNewValue);
. This won’t trigger a new ChangeEvent
.For more information, see Change events
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 툴킷 이벤트에 응답할 수 있습니다.
이벤트에 대한 응답 방식은 상황에 따라 달라집니다.
콜백과 기본 액션 간의 차이는 다음과 같습니다.
기본 액션은 클래스의 모든 인스턴스에 적용됩니다. 기본 액션을 구현하는 클래스는 해당 인스턴스에 등록된 콜백도 보유할 수 있습니다.
클래스는 기본 액션을 구현할 때 VisualElement
의 새로운 서브 클래스를 파생하고, ExecuteDefaultActionAtTarget()
메서드 또는 ExecuteDefaultAction()
메서드, 또는 두 메서드 모두를 구현해야 합니다.
기본 액션은 시각적 요소 서브 클래스의 각 인스턴스가 이벤트를 수신하면 해당 이벤트에서 실행됩니다. 아래 예제처럼 ExecuteDefaultActionAtTarget()
및 ExecuteDefaultAction()
을 오버라이드하여 기본 액션을 커스터마이즈할 수 있습니다.
override void ExecuteDefaultActionAtTarget(EventBase evt)
{
// Call the base function.
base.ExecuteDefaultActionAtTarget(evt);
if (evt.eventTypeId == MouseDownEvent.TypeId())
{
// ...
}
else if (evt.eventTypeId == MouseUpEvent.TypeId())
{
// ...
}
// More event types
}
ExecuteDefaultAction()
에서 기본 액션을 구현하면 기본 액션의 실행을 중지하거나 막을 수 있습니다.
타겟 기본 액션이 부모 콜백 전에 실행되도록 만들고 싶으면 ExecuteDefaultActionAtTarget()
에서 기본 액션을 구현하십시오.
기본 액션은 요소 타입이 이벤트를 수신할 때 나타나야 하는 동작으로 볼 수 있습니다. 예를 들어, 체크박스는 클릭 이벤트에 대한 응답으로 상태를 토글해야 합니다. 이를 실행하기 위해 모든 체크박스에 콜백을 등록하는 대신 기본 액션 가상 함수를 오버라이드할 수 있습니다.
The following are best practices for custom controls.
기본 액션으로 요소의 동작을 구현해야 합니다. 인스턴스에 부착된 콜백에서 PreventDefault()
를 호출하여 기본 요소 동작을 취소할 수 있습니다.
동작을 기본 액션으로 구현하는 경우 추가적인 이점은 다음과 같습니다.
유연성 향상을 위해 이벤트 타겟의 기본 액션을 이벤트 디스패치 프로세스 동안 두 지점에서 실행할 수 있습니다.
ExecuteDefaultActionsAtTarget()
.ExecuteDefaultActions()
.ExecuteDefaultActions()
에서 클래스 기본 액션을 구현하십시오. 이렇게 하면 더 많은 클래스 오버라이드 옵션을 이용할 수 있습니다. 이벤트 전파 프로세스의 트리클다운 단계 또는 버블업 단계 동안 PreventDefault()
를 호출하여 클래스를 오버라이드할 수 있습니다.
이벤트가 부모 요소로 전파되어서는 안 되는 경우, 기본 액션 실행 중 이벤트 전파를 중단해야 합니다. 예를 들어, 텍스트 필드가 콘텐츠를 삭제하는 Delete
키와 같이 필드 값을 변경하는 KeyDownEvent
를 수신합니다. 이 이벤트는 부모 시각적 요소로 전파되어서는 안 됩니다. 이러한 기본 액션을 구현하려면 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 affect the ExecuteDefaultActionAtTarget()
action during the bubble-up phase.