UI 工具包事件系统监听来自操作系统或脚本的事件,并使用 EventDispatcher 将这些事件分发到视觉元素。事件分发程序为发送的每个事件确定相应分发策略。一旦确定后,分发程序就会执行该策略。
视觉元素实现了几个事件的默认行为。这可能涉及额外事件的创建和执行。例如,一个 MouseMoveEvent
可以生成一个额外的 MouseEnterEvent
和一个 MouseLeaveEvent
。这些事件进入队列并在当前事件之后处理。例如,MouseMoveEvent
在 MouseEnterEvent
和 MouseLeaveEvent
事件之前完成处理。
每个事件类型都有自己的分发行为。每种事件类型的行为分为三个阶段:
有关每种事件类型的分发行为的列表,请参阅事件参考页面 。
事件分发程序选择事件目标后,会计算事件的传播路径。传播路径是接收事件的视觉元素的有序列表。传播路径按以下顺序发生:
大多数事件类型将沿着传播路径发送到所有元素。某些事件类型跳过冒泡阶段,某些事件类型仅发送到事件目标。
如果元素被隐藏或禁用,它将不会接收事件。事件仍会传播到被隐藏或禁用的元素的祖先和后代。
在事件沿着传播路径行进时,Event.currentTarget
更新为当前正在处理该事件的元素。在事件回调函数中,有两个属性记录了分发行为:
Event.currentTarget
是注册回调的视觉元素。Event.target
是发生事件的元素,例如鼠标正下方的元素。事件的目标取决于事件类型。对于鼠标事件,目标最常见的是直接位于鼠标下方最上层的可选择元素。对于键盘事件,目标是当前获得焦点的元素。
UI 工具包事件有一个 target
属性,包含对发生事件的元素的引用。对于大多数源自操作系统的事件,分发过程会自动找到事件目标。
目标元素存储在 EventBase.target
中并且在分发过程中不会改变。属性 Event.currentTarget
会更新为当前正在处理该事件的视觉元素。
大多数鼠标事件使用拾取模式来确定其目标。VisualElement
类有一个支持以下值的 pickingMode
属性:
PickingMode.Position
(默认值):根据位置矩形执行拾取。PickingMode.Ignore
:阻止因鼠标事件而拾取。可以覆盖 VisualElement.ContainsPoint()
方法来执行自定义的交集逻辑。
在 MouseDownEvent
之后,某些元素必须捕获指针位置,以确保能接收所有后续的鼠标事件,即使光标不再悬停在该元素上。例如,在单击按钮、滑动条或滚动条时就属于这种情况。
要捕获鼠标,请调用 element.CaptureMouse()
或 MouseCaptureController.CaptureMouse()
。
要释放鼠标,请调用 MouseCaptureController.ReleaseMouse()
。如果在调用 CaptureMouse()
时已经有另一个元素正在捕获鼠标,该元素将收到 MouseCaptureOutEvent
并失去此捕获。
在应用程序中,任何时候都只能有一个元素具有捕获。当元素具有捕获时,该元素便是除鼠标滚轮事件之外的所有后续鼠标事件的目标。这仅适用于尚未设置目标并依赖分发过程来确定目标的鼠标事件。
有关更多信息,请参阅捕获事件。
每个 UI 工具包面板都有一个焦点环,用于定义元素的焦点顺序。默认情况下,对视觉元素树执行深度优先搜索 (DFS) 确定元素的焦点顺序。例如,以下所示的树的焦点顺序将是 F、B、A、D、C、E、G、I、H。
有些事件使用焦点顺序来确定哪个元素获得焦点。例如,键盘事件的目标是当前获得焦点的元素。
使用 focusable
属性可控制元素的可聚焦性。默认情况下,VisualElements
无法聚焦,但是某些子类(例如 TextField
)默认可聚焦。
使用 tabIndex
属性可按如下方式控制焦点顺序(tabIndex
默认值为 0):
tabIndex
为负,则无法用 Tab 键导航到该元素。tabIndex
为零,该元素保持默认的 Tab 顺序(通过焦点环算法确定的顺序)。tabIndex
为正,该元素将置于 tabIndex
为零 (tabIndex = 0
) 或 tabIndex
更小的其他元素之前。Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.