前期配置:环境配置参考教程一,手部模型参考教程二,场景基于上一篇搭建。
最终效果:手部射线(初始不可见)对准 UI 显示,按下手柄 Trigger 键与可交互 UI(如 Button、Toggle、Slider 等)互动。
制作 World Space 模式的 UI
创建 Canvas 物体,将其 Canvas 组件的 Render Mode(屏幕空间) 改为 World Space(世界空间),调整大小和位置,添加 UI 元素(如 Button、Toggle、Slider)。
添加 Tracked Device Graphic Raycaster 脚本
删除 Canvas 原有的 Graphic Raycaster 组件,添加 Tracked Device Graphic Raycaster 脚本,使 UI 能响应射线选中高亮,勾选 ignore reverse 选项可限制从正面点击。
添加 XR UI Input Module 脚本
创建ui画布的时候,会自动创建EventSystem 物体
在 EventSystem 物体添加 XR UI Input Module 脚本,移除原有的 Standalone Input Module 脚本,用于管理 XR 中 UI 的输入。
添加 UI 射线相关脚本
负责 UI 射线的物体和挂载的脚本:
基于 XR Origin,在 Left Controller 和 Right Controller 下创建 UI Ray Interactor 物体,添加 XR Ray Interactor(Line Type 为 Straight Line)、Line Renderer、XR Interactor Line Visual 脚本、Sorting Group 组件。
为什么控制 UI 射线的物体不用添加 XR Controller
- UI Ray Interactor 物体沿用父物体 Left Controller 或 RightHand Controller 的 XR Controller 处理输入,无需额外添加 XR Controller。
** Sorting Group 组件** - Sorting Group 这个组件给了我们自定义的功能,可以设置层级。是否需要添加这个组件就看大家的需求了
过滤 UI 射线的目标:
将 Left Controller 和 Right Controller 物体上 XR Ray Interactor 脚本的 Raycast Mask 从 Everything 改为 UI,避免射线在非 UI 物体上激活。
使射线射到 UI 上时才显示射线颜色:
修改 XR Interactor Line Visual 脚本的 Invalid Color Gradient 透明度为 0,实现射线仅在射中 UI 时显示。
改变射线发射的位置:
在手部模型下创建子物体作为射线起始点,调整位置和方向,将其拖入 XR Ray Interactor 脚本的 Ray Origin Transform。
通过按下手柄菜单键控制 UI 的显示与隐藏:
在 XRI Default Input Actions 中配置菜单键 Action,在 XRI LeftHand 中添加名为 Menu 的 Action,设置为 Button 类型,绑定 LeftHand 的 MenuButton。
编写 UIController 脚本,获取配置的 Action 并在按下时切换 Canvas 的显示状态,将脚本挂载到 LeftHand Controller 物体并关联 Action 和 Canvas。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class UIController : MonoBehaviour
{
public InputActionReference menu;
public Canvas canvas;
private void Start()
{
if(menu != null)
{
menu.action.Enable();
menu.action.performed += ToggleMenu;
}
}
private void ToggleMenu(InputAction.CallbackContext context)
{
canvas.enabled = !canvas.enabled;
}
}
注意:使用 Dropdown 时 UI 射线可能看不到,可在 UI Ray Interactor 下的 Sorting Group 中添加层解决。