本页面包含将事件系统和输入系统与__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary 工具包结合使用的常见问题。
方法有两种:
第一种方法
在场景中添加事件系统组件,添加方式与从 com.unity.uGUI 包创建基于游戏对象的 UI 内容相同。
使用 EventSystem.current.IsPointerOverGameObject 方法,如果指针位于 uGUI 或 UI 工具包中的 UI 内容上方,则返回 true。
使用 EventSystem.current.RaycastAll 方法以查看鼠标下的视觉元素。
交叉的 UI 工具包面板在事件系统的环境中通过游戏对象表示:
PanelRaycaster 和 PanelEventHandler。这两个组件都有一个 panel 属性,该属性返回其目标 IPanel。在指针下找到面板后,调用 panel.Pick 方法以查找指针位置处的视觉元素。
必须使用 RuntimePanelUtils.ScreenToPanel 方法将指针的屏幕坐标变换为面板坐标。
uGUI 的屏幕坐标系使用左下角原点,而 UI 工具包屏幕坐标从左上角表示。两个系统之间的转换需要使用 yTopLeft = Screen.height - yBottomLeft 镜像 Y 坐标,反之亦然。
第二种方法
UIDocument.rootVisualElement 属性,用于获取指针下可能包含的所有运行时面板的列表,您可以收集这些面板panel.Pick,直到找到返回视觉元素的面板。
要重新映射基本 UI 操作,请执行以下操作:
com.unity.uGUI 包创建基于游戏对象的 UI 内容相同。注意:映射到 Tab 和 Shift+Tab 输入的操作无法重新映射,因为未通过事件系统输入模块公开。
可以将方向导航配置为具有默认目标以外的其他目标。
以下代码示例允许元素 A 分别在向上、向下、向左和向右导航时导航到元素 U、D、L、R:
A.RegisterCallback <NavigationMoveEvent>(e =>
{
switch(e.direction)
{
case NavigationMoveEvent.Direction.Up: U.Focus(); break;
case NavigationMoveEvent.Direction.Down: D.Focus(); break;
case NavigationMoveEvent.Direction.Left: L.Focus(); break;
case NavigationMoveEvent.Direction.Right: R.Focus(); break;
}
e.PreventDefault();
});
是的。可以使用检视面板窗口中 EventSystem 的 StandaloneInputModule 或 InputSystemUIInputModule 字段来控制每个操作的输入映射。但是,由于这些操作与 uGUI 输入共享,因此也会更改 uGUI 控件。
要在不影响 uGUI 控件的情况下重新映射 UI 工具包输入,请禁用 UI 工具包的运行时事件处理,并手动将所有事件发送到面板。为此,请在当前 EventSystem 的启动方法(例如场景组件的 Awake 方法)启动之前调用 EventSystem.SetUITookitEventSystemOverride(null, true, false);。有关此 uGUI 方法的更多信息,请参阅 SetUITookitEventSystemOverride。
在给定时间,例如首次加载游戏场景时,可能没有元素或面板获得焦点。在这种情况下,键盘导航不会从可预测的第一个元素开始。对于完全不使用鼠标的游戏,这可能是一个问题。
可以添加 C# 脚本,以便从一开始就实现可预测的导航行为,并将脚本附加到与您选择负责获取初始焦点的元素的 UIDocument 相同的游戏对象。
假设脚本命名为 FirstFocus,并且初始聚焦元素命名为 first-focused。在脚本的 Start() 方法中,添加一行以聚焦该元素,如下所示:
public class FirstFocus : MonoBehaviour
{
void Start()
{
FocusFirstElement();
}
public void FocusFirstElement()
{
GetComponent<UIDocument>().rootVisualElement.
Q<VisualElement>("first-focused").Focus();
}
}
注意:如果禁用 UIDocument 的游戏对象,则会从头开始重新创建其所有底层层级视图。因此,必须在重新启用游戏对象后再次运行自定义 FocusFirstElement() 方法。