第 18 课
手柄控制器介绍UI的制作与交互
本课将使用上一课的凝视判断能力,为左右手柄制作情境式帮助界面。你会配置手柄凝视和快速移动保护,创建世界空间画布,制作可以自由拉伸的圆角标签,完成文字锚点与清晰度设置,再通过 Facing Entered 和 Facing Exited 事件控制整套说明的显示与隐藏。
制作看向手柄时出现的按键说明
为左右 PICO 手柄制作跟随移动的三维说明标签:看向手柄时了解按键功能,移开视线或快速挥动手柄时自动隐藏。

完成本课后,看向左右手柄时会在对应按键旁显示功能说明;移开视线后,整套说明会自动隐藏。
点击图片可以查看完整截图学完你将能够
学习目标
- 说明手柄说明为什么适合在需要时显示、移开视线后隐藏。
- 区分 Controller(控制器)对象与 Hand(手部跟踪)对象。
- 说明 Gaze Interactor、凝视判断组件、事件和说明界面的协作关系。
- 根据 Facing Threshold 判断凝视范围变宽还是变窄。
- 解释快速移动距离和冷却时间如何减少界面晃动。
- 创建位于手柄下方的世界空间 XR 画布。
- 根据手柄模型调整画布的本地位置、旋转和缩放。
- 把圆角图片设置为 Sprite(精灵图)并使用九宫格边界。
- 使用 Sliced(九宫格切片)模式拉伸背景而不破坏圆角。
- 使用双向拉伸锚点让文字跟随标签尺寸变化。
- 区分精灵图单位换算倍率和画布动态像素密度的作用。
- 完成左手柄的移动、菜单、抓取和界面交互说明。
- 复制并调整右手柄的移动、跳跃、抓取和界面交互说明。
- 使用 SetActive 正确绑定显示与隐藏事件。
- 根据不显示、一直显示、模糊、变形和闪烁等现象定位问题。
开始操作前
准备工作
- 确认 XR Origin Hands 能够正常运行,左右控制器模型会跟随实体手柄。
- 在 Camera Offset 下找到 Main Camera、Gaze Interactor、Left Controller 和 Right Controller。
- 确认场景中同时保留 Controller 与 Hand 对象,并能区分两者。
- 确认项目中已经存在第 17 课使用的 CalloutGazeController。
- 确认 GameObject > XR 菜单中可以创建 UI Canvas。
- 确认场景中已经存在可用于 XR 界面的 EventSystem(事件系统)。
- 打开 Hierarchy(层级面板)、Inspector(属性面板)、Scene 和 Game 窗口。
- 保存 MainScene,并进入一次运行模式确认手柄模型可以正常显示。
本课学习路线
按照学习模块逐步完成
每个模块都包含理解、跟随操作和独立实践。帮助应该在你需要时出现
理解手柄说明的显示时机
第一次使用虚拟现实手柄时,你既需要认识按键位置,也需要知道按键在当前项目中的功能。如果八个标签始终跟随两只手柄显示,又会遮挡展厅并分散注意力,因此本课采用“看向显示、移开隐藏”的按需帮助方式。不同状态下的界面结果
说明界面根据你的当前动作出现,不需要额外打开独立帮助页面。
左右滑动表格,可查看完整内容
| 当前状态 | 界面结果 | 设计原因 |
|---|---|---|
| 正在看向某只手柄 | 显示这只手柄的说明 | 此时最可能需要了解按键 |
| 已经移开视线 | 隐藏说明 | 把视野还给展厅内容 |
| 手柄突然快速移动 | 立即隐藏并短暂等待 | 减少文字剧烈晃动 |
| 手柄稳定且重新进入视线 | 再次显示 | 随时保留学习机会 |
手柄四类按键与项目功能
专业名称用于对应 Unity 输入动作,中文说明直接告诉你当前项目中的实际功能。
左右滑动表格,可查看完整内容
| 按键名称 | 中文理解 | 常见位置 | 本项目功能 |
|---|---|---|---|
| Joystick | 摇杆 | 手柄正面上方 | 移动 |
| Primary Button | 主按钮 | 左手 X、右手 A | 左侧菜单、右侧跳跃 |
| Grip | 抓取键 | 手柄侧面 | 抓取物体 |
| Trigger | 扳机键 | 手柄前方 | 与界面进行交互 |
在手柄模型上找到四类按键
观察左右手柄模型,指出每类按键的位置并说出它在项目中的作用。
- 指出左、右摇杆,并说明它们当前用于移动。
- 指出左 X 键,说明它用于打开系统菜单。
- 指出右 A 键,说明它用于跳跃。
- 分别指出 Grip 与 Trigger 的位置和用途。
- 说明左右手柄中哪一个标签文字不能直接复制。
方向、判断、事件和显示各自负责一件事
理解凝视、控制器与说明界面的关系
说明界面本身不计算你正在看哪里。Gaze Interactor 提供视线方向,左右手柄分别判断自己是否进入视线范围,再通过事件控制各自的说明界面。沿箭头阅读:一个 Gaze Interactor 提供视线方向;Left Controller 与 Right Controller 分别判断;每只手柄只控制自己的说明界面。
手机上可左右滑动;点击图片可以查看完整图四个角色的职责
把职责分开后,凝视异常、事件错误和界面布局问题可以分别定位。
左右滑动表格,可查看完整内容
| 角色 | 主要职责 | 本课配置位置 |
|---|---|---|
| Gaze Interactor | 提供视线位置与前方方向 | Camera Offset 下 |
| Callout Gaze Controller | 判断你是否面向当前手柄 | 左右 Controller |
| Facing Entered / Exited | 报告进入或离开凝视范围 | 凝视组件事件 |
| 说明界面 | 根据事件显示或隐藏四个标签 | 对应 Controller 子对象 |
Controller 与 Hand 的区别
本课制作的是实体手柄说明,所以判断组件必须跟随控制器对象。
左右滑动表格,可查看完整内容
| 对象 | 表示内容 | 本课是否使用 |
|---|---|---|
| Left / Right Controller | 实体控制器的跟随、模型和输入交互 | 使用 |
| Left / Right Hand | 手部跟踪得到的手模型和关节 | 不用于本课手柄说明 |
为什么界面要成为 Controller 的子对象
子对象会继承父对象的移动、旋转和缩放。把左侧说明放到 Left Controller 下面后,手柄移动时说明会一起移动,不需要另外编写跟随代码。
界面中各标签使用的是相对于手柄的本地位置,而不是场景中的绝对位置。复制到右手柄后,需要重新调整这些本地位置。
判断组件要一直运行,只切换界面子对象
Callout Gaze Controller 位于 Left Controller 或 Right Controller 上,它需要持续判断你是否看向手柄。即使说明暂时隐藏,Controller 和凝视组件也必须保持启用。
真正需要显示或隐藏的是 Controller 下面的 LControllerIntroUI 或 RControllerIntroUI。这样界面隐藏后,凝视组件仍能发现你再次看向手柄,并重新显示说明。
SetActive 的两个参数
SetActive 用来切换一个对象及其子对象是否启用。本课始终把它用在说明界面根对象上。
左右滑动表格,可查看完整内容
| 调用方式 | 界面结果 | 使用时机 |
|---|---|---|
| 说明界面.SetActive(true) | 说明界面及其标签显示 | 刚进入凝视范围 |
| 说明界面.SetActive(false) | 说明界面及其标签隐藏 | 移开视线或手柄快速移动 |
从看向手柄到界面显示的完整调用链
沿着每一行向下阅读,可以看清方向、判断、事件和界面显示是怎样接在一起的。
左右滑动表格,可查看完整内容
| 顺序 | 执行者 | 发生的事情 |
|---|---|---|
| 1 | Gaze Interactor | 提供当前视线的位置和前方方向 |
| 2 | Callout Gaze Controller | 比较视线方向与当前手柄方向,判断是否进入凝视范围 |
| 3 | Facing Entered | 判断结果从“未看向”变为“正在看向”时触发进入事件 |
| 4 | 事件绑定 | 调用对应说明界面的 SetActive(true) |
| 5 | LControllerIntroUI 或 RControllerIntroUI | 启用界面根对象,并一起显示它下面的四个标签 |
沿架构图说明一次显示过程
从你转头开始,依次指出方向提供者、判断者、事件和显示对象。
- Gaze Interactor 提供当前前方方向。
- Left Controller 判断视线是否朝向自己。
- Facing Entered 报告刚进入有效范围。
- LControllerIntroUI 接收事件并显示。
- 说明为什么右手柄不会被左手柄事件控制。
看得更准,移动过快时先隐藏
配置手柄凝视范围与快速移动保护
Callout Gaze Controller 比较视线前方与手柄方向的点积。方向越接近,结果越接近 1;Facing Threshold 越接近 1,你需要越准确地看向手柄。点积与凝视范围
距离先通过标准化排除,只比较视线与手柄之间的方向关系。
左右滑动表格,可查看完整内容
| 点积结果 | 方向关系 | 判断含义 |
|---|---|---|
| 接近 1 | 两个方向接近一致 | 基本看向手柄 |
| 接近 0 | 两个方向接近垂直 | 手柄位于视野侧面 |
| 小于 0 | 两个方向相反 | 手柄位于视线后方 |
Facing Threshold 参考值
先使用本课的集中范围,再在 PICO 设备中根据真实佩戴体验小幅调整。
左右滑动表格,可查看完整内容
| 阈值 | 大约允许夹角 | 直观结果 |
|---|---|---|
| 0.85 | 31.8° | 范围较宽,视野边缘也可能显示 |
| 0.949 | 18.4° | 范围较集中,需要明确看向手柄 |
| 0.95 | 18.2° | 与本课效果接近 |
脚本先检查手柄位移。快速移动时立即隐藏并开始冷却;手柄稳定后才继续计算方向点积。
手机上可左右滑动;点击图片可以查看完整图左右手柄统一设置
两个手柄使用相同的方向来源和初始参数,但各自保留独立的凝视事件。
左右滑动表格,可查看完整内容
| 属性 | 设置值 | 作用 |
|---|---|---|
| Gaze Transform | Gaze Interactor | 提供视线位置和方向 |
| Facing Threshold | 约 0.949 | 限制显示角度范围 |
| Large Movement Distance Threshold | 0.05 | 单帧移动约 5 厘米时判定快速移动 |
| Large Movement Cool Down Time | 0.25 | 移动后短暂等待再允许显示 |
为左右 Controller 添加凝视组件
- 01
在 Camera Offset 下同时选择 Left Controller 和 Right Controller。
- 02
添加 Callout Gaze Controller。
- 03
把 Camera Offset 下、与 Main Camera 同级的 Gaze Interactor 拖到两个 Gaze Transform。
- 04
把两个 Facing Threshold 调整到约 0.949。
- 05
保持快速移动距离为 0.05,冷却时间为 0.25。
- 06
为左右手柄各准备一个临时小球,并把两个小球都设为初始停用。
- 07
左手柄事件只控制左侧小球:Entered 使用 SetActive(true),Exited 使用 SetActive(false)。
- 08
右手柄事件只控制右侧小球,并使用相同的 true / false 设置。
- 09
分别看向左右手柄,确认两个小球可以独立显示和隐藏。
- 10
确认后删除两个临时小球,再继续制作正式说明界面。
完成看向、移开和快速移动测试
分别观察左右手柄,并快速挥动其中一只手柄。
- 看向左手柄时,只触发左侧进入事件。
- 移开视线后,触发左侧离开事件。
- 右手柄能够独立完成相同过程。
- 快速移动时立即触发隐藏。
- 稳定约 0.25 秒后重新看向,可以再次显示。
让说明像三维物体一样跟随手柄
创建并摆放左手柄世界空间画布
Canvas(画布)用于承载界面元素。手柄说明必须出现在手柄旁边并跟随移动,因此使用 World Space(世界空间)画布,而不是固定在屏幕上的画布。两种画布模式
世界空间画布可以像普通三维物体一样设置位置、旋转和缩放。
左右滑动表格,可查看完整内容
| 画布模式 | 位置方式 | 适合内容 |
|---|---|---|
| 屏幕空间 | 固定在显示画面上 | 传统游戏状态栏 |
| World Space | 放置在三维场景中 | 手柄提示、展品说明和空间菜单 |
创建 XR UI Canvas
- 01
在 Hierarchy 中右键 Left Controller。
- 02
选择 XR > UI Canvas。
- 03
确认 Canvas 已成为 Left Controller 的子对象。
- 04
确认 Render Mode 为 World Space。
- 05
确认 Event Camera 指向 Main Camera。
- 06
确认存在 Canvas Scaler 与 Tracked Device Graphic Raycaster。

观察三处:Canvas 位于 Left Controller 下;Render Mode 为 World Space;属性面板中保留 Canvas Scaler 和 XR 射线组件。
点击图片可以查看完整截图当前手柄模型的起始参考值
这些数值用于帮助找到画布,不需要死记。不同模型和父对象比例需要重新微调。
左右滑动表格,可查看完整内容
| Rect Transform 属性 | 参考值 |
|---|---|
| Position X / Y / Z | -0.0148 / 0.0087 / -0.0557 |
| Width / Height | 100 / 100 |
| Rotation X / Y / Z | -90 / 0 / 0 |
| Scale X / Y / Z | 约 0.0005669501 |
为什么画布需要很小的缩放
界面宽高通常按像素思路设置,例如 100 × 100;三维场景通常按米理解。如果世界空间画布保持 Scale = 1,它会显得非常巨大。
正确调整顺序是先缩小到能看到完整画布,再调整旋转使正面朝向你,最后调整位置避免穿进手柄。最终大小需要在 PICO 设备的真实观察距离中确认。
把画布放到左手柄合适位置
调整 Canvas 的本地变换,并在运行模式中观察它如何跟随手柄。
- 画布正面朝向你,不背对观察方向。
- 画布靠近手柄,但不穿进模型。
- 画布不会盖住摇杆、主按钮、抓取键和扳机键。
- 移动和旋转手柄时,画布保持相对位置。
- 使用实体手柄姿态重新确认大小和方向。
使用半透明背景提高可读性,用九宫格保护圆角
制作可以拉伸的圆角标签背景
纯文字容易与展厅背景混在一起。本模块先建立半透明深色 Image,再把圆角图片导入为 Sprite,通过九宫格边界和 Sliced 模式让不同长度的标签都保持相同圆角。创建第一个半透明 Image
- 01
在 Canvas 下创建 UI > Image。
- 02
把 Image 放到左摇杆附近。
- 03
先设置适合短文字的宽度和高度。
- 04
把颜色调为接近黑色。
- 05
把透明度降低到约 60%,让场景仍能隐约透过背景。

颜色参考为 R=10、G=9、B=9、A=154。A 使用 0—255 范围时,154 大约是 60% 不透明。
点击图片可以查看完整截图下载圆角标签背景
把图片放入 Unity 项目的纹理目录,随后按本模块步骤设置为 Sprite 并添加九宫格边界。
- 图片尺寸为 400 × 400。
- 用于 UI Image 的圆角背景。
- 需要设置 Border 后再使用 Sliced 模式。
把圆角图片设置为 Sprite
- 01
选中刚导入的圆角图片。
- 02
把 Texture Type 改为 Sprite (2D and UI)。
- 03
保持 Sprite Mode = Single。
- 04
保持 Pixels Per Unit = 100。
- 05
保持 Wrap Mode = Clamp,Filter Mode = Bilinear。
- 06
单击 Apply。

重点确认 Texture Type 已设为 Sprite (2D and UI),并在应用设置后出现 Sprite Editor 按钮。
点击图片可以查看完整截图需要时安装 2D Sprite
- 01
如果 Sprite Editor 无法打开,进入 Window > Package Manager。
- 02
左上角选择 Unity Registry。
- 03
搜索并选择 2D Sprite。
- 04
单击 Install,并等待 Unity 完成导入。
- 05
软件包版本会随项目环境不同,以当前 Unity 推荐的兼容版本为准。
- 06
重新选中圆角图片并打开 Sprite Editor。

2D Sprite 提供 Sprite Editor。版本号可能与你当前项目不同,选择与当前 Unity 兼容的版本即可。
点击图片可以查看完整截图为圆角图片设置 Border
- 01
打开 Sprite Editor。
- 02
把四条绿色边界线放在圆角结束的位置。
- 03
参考输入 Left=44、Right=46、Top=39、Bottom=40。
- 04
确认绿色边界没有切进圆角主体。
- 05
单击 Apply 保存。
- 06
回到 Image,把 Source Image 改为圆角图片。
- 07
把 Image Type 改为 Sliced,并保持 Fill Center 开启。

四条绿色线把四个圆角与可拉伸区域分开。应用后,Sliced 模式只拉伸边和中心,不会把圆角一起压扁。
点击图片可以查看完整截图九宫格的九个区域
四个角保持形状,四条边只沿一个方向拉伸,中心填满剩余空间。
左右滑动表格,可查看完整内容
| 左列 | 中列 | 右列 |
|---|---|---|
| 左上角 | 上边 | 右上角 |
| 左边 | 中心 | 右边 |
| 左下角 | 下边 | 右下角 |
横向拉伸并观察圆角
改变第一个标签的宽度,比较设置 Border 前后的四个圆角。
- Image Type 已改为 Sliced。
- 属性面板不再提示图片没有 Border。
- 短标签和长标签的圆角曲率接近一致。
- 背景中心可以扩展,不出现明显断裂。
- 透明度足以提高文字可读性,又不会完全挡住手柄。
让文字始终位于背景中,并从正常距离清楚可读
添加文字、拉伸锚点并提高清晰度
本课使用当前项目已有的 Text (Legacy) 文字组件。先完成白色居中文字,再让文字矩形横向和纵向都跟随父 Image,最后分别调整精灵图的单位换算比例和画布中文字的动态像素密度。第一个“移动”标签文字设置
Text (Legacy) 位于 Image 下方,并使用父对象尺寸作为自己的显示范围。
左右滑动表格,可查看完整内容
| 属性 | 设置 |
|---|---|
| Text | 移动 |
| Color | 白色 |
| Horizontal / Vertical Alignment | 居中 / 居中 |
| Font Size | 先使用 14,再按设备观察调整 |
| Horizontal Overflow | Wrap |
| Vertical Overflow | Truncate |
创建并设置“移动”文字
- 01
右键第一个标签 Image,选择 UI > Legacy > Text。
- 02
确认 Text (Legacy) 已成为 Image 的子对象。
- 03
把 Text 内容改为“移动”,颜色设为白色。
- 04
把水平和垂直 Alignment 都设为居中。
- 05
Font Size 先设为 14。
- 06
Horizontal Overflow 设为 Wrap,Vertical Overflow 设为 Truncate。
- 07
在 Game 窗口确认文字已经显示在深色圆角背景上。
设置横纵双向拉伸锚点
- 01
选中 Image 下的 Text (Legacy)。
- 02
打开 Rect Transform 的 Anchor Presets。
- 03
按住 Alt + Shift。
- 04
选择右下角横向、纵向都拉伸的预设。
- 05
确认 Left、Right、Top、Bottom 接近 0。
- 06
改变 Image 宽高,确认文字仍在背景内部并保持居中。

按住 Alt + Shift 选择右下角预设,使文字的四条边同时贴合父 Image。
点击图片可以查看完整截图三个像素相关参数的分工
三个参数位于不同组件,作用也不同。图片倍率不会提高源图片分辨率。
左右滑动表格,可查看完整内容
| 参数 | 所在组件 | 主要影响 | 参考值 |
|---|---|---|---|
| Pixels Per Unit Multiplier | 单个 Image | 精灵图单位换算与九宫格边框厚度 | 约 11 |
| Dynamic Pixels Per Unit | Canvas Scaler | 文字等动态内容的像素密度 | 约 5 |
| Reference Pixels Per Unit | Canvas Scaler | 精灵图与画布单位换算基准 | 100 |

该示例把 Pixels Per Unit Multiplier 设为 11,用于调整九宫格边框映射到画布后的厚度;它不会增加源图片的分辨率。
点击图片可以查看完整截图
Dynamic Pixels Per Unit 提高到 5,主要改善世界空间画布中文字等动态内容的像素密度。
点击图片可以查看完整截图完成第一个清晰标签
制作“移动”标签,并从正常手柄观察距离判断可读性。
- 文字为白色并水平、垂直居中。
- 文字锚点横纵双向拉伸。
- Image 的像素倍率约为 11,圆角边框厚度合适。
- Canvas 的动态像素密度约为 5。
- 改变背景宽度后文字仍完整显示。
- 在 PICO 设备中从正常距离可以读清,不盲目继续放大参数。
先把一个标签做完整,再复制成熟设置
完成左手柄四个按键说明
四个标签的视觉样式相同,只有名称、位置、旋转、宽度和文字不同。复制已经完成的“移动”标签,可以保持背景、锚点和清晰度设置一致。从 JoystickTip 完成四个标签
- 01
把第一个完整标签重命名为 JoystickTip,放到左摇杆附近,文字保持“移动”。
- 02
复制并重命名为 PrimaryTip,放到 X 键附近,文字改为“菜单”。
- 03
复制并重命名为 GripTip,放到侧面抓取键附近,文字改为“抓取”。
- 04
复制并重命名为 TriggerTip,放到扳机键附近,文字改为“UI交互”。
- 05
增加 TriggerTip 的宽度,确保四个字完整显示。
- 06
把 Canvas 重命名为 LControllerIntroUI。
左手柄标签映射
对象名用于场景管理,中文文字说明按键在当前项目中的实际作用。
左右滑动表格,可查看完整内容
| 标签对象名 | 对应按键 | 显示文字 | 功能说明 |
|---|---|---|---|
| JoystickTip | 左摇杆 | 移动 | 控制行走方向 |
| PrimaryTip | X 键 | 菜单 | 打开系统菜单 |
| GripTip | Grip | 抓取 | 拿起可交互物体 |
| TriggerTip | Trigger | UI交互 | 点击按钮或操作界面 |
为什么四个标签共用一张 Canvas
一张 Canvas 下可以放置多个 Image 和 Text。四个标签共用 LControllerIntroUI 后,可以一次显示或隐藏整套说明,也能共享 Canvas Scaler 和 XR 射线设置。
世界空间 Canvas 的子对象仍然可以分别在三维空间中移动和旋转,不要求四个标签都位于同一个平面。
逐个核对左手柄标签
从摇杆开始沿手柄轮廓检查四个标签的位置、文字和宽度。
- 每个标签只对应一个明确按键。
- PrimaryTip 位于 X 键附近并显示“菜单”。
- TriggerTip 足够宽,“UI交互”没有被截断。
- 标签不穿进手柄,也不会互相重叠。
- LControllerIntroUI 下正好包含四个标签。
复制整套界面,再根据左右功能差异调整
复制并调整右手柄说明界面
左右手柄外形大体对称,不需要从空画布重新制作。把整套左侧界面复制到 Right Controller 后,重新摆放四个标签,并把右侧主按钮说明从“菜单”改为“跳跃”。建立 RControllerIntroUI
- 01
选中 LControllerIntroUI,按 Ctrl + D 创建副本。
- 02
把副本拖到 Right Controller 下方。
- 03
确认层级缩进表示它已成为右手柄子对象。
- 04
重命名为 RControllerIntroUI。
- 05
重新调整画布和四个标签的本地位置与旋转。
- 06
确认文字正面朝向你,标签不穿进手柄。
右手柄标签映射
右手柄的主按钮功能与左手不同,复制后必须修改 PrimaryTip。
左右滑动表格,可查看完整内容
| 标签对象名 | 右手柄位置 | 显示文字 |
|---|---|---|
| JoystickTip | 右摇杆附近 | 移动 |
| PrimaryTip | A 键附近 | 跳跃 |
| GripTip | 右侧抓取键附近 | 抓取 |
| TriggerTip | 右侧扳机键附近 | UI交互 |
说明文字必须匹配当前输入动作
左 X 键在当前项目中打开菜单,右 A 键负责跳跃,因此右侧 PrimaryTip 不能继续显示“菜单”。
如果项目已经把右摇杆改为转向,右侧 JoystickTip 也应改为“转向”。界面文字应描述你实际能够执行的动作,而不是机械沿用复制内容。
完成右侧镜像布局
围绕右手柄实际按键重新摆放标签,并与左侧界面比较大小和风格。
- RControllerIntroUI 是 Right Controller 的子对象。
- PrimaryTip 位于 A 键附近并显示“跳跃”。
- 其他三个标签对应正确按键。
- 左右标签的颜色、圆角、字体和清晰度保持一致。
- 右侧标签之间不重叠,也不会穿入模型。
只切换说明界面,始终保留手柄与凝视判断运行
绑定显示事件并完成整体验证
GameObject.SetActive 可以启用或停用一个对象及其子对象。本课只切换 LControllerIntroUI 与 RControllerIntroUI,不能关闭 Controller,否则凝视组件也会停止,重新看向时便无法再次显示。左右手柄事件映射
Entered 的布尔参数为 true,Exited 为 false;左右事件必须控制各自的界面根对象。
左右滑动表格,可查看完整内容
| 判断对象 | 事件 | 控制对象 | SetActive 参数 |
|---|---|---|---|
| Left Controller | Facing Entered | LControllerIntroUI | true |
| Left Controller | Facing Exited | LControllerIntroUI | false |
| Right Controller | Facing Entered | RControllerIntroUI | true |
| Right Controller | Facing Exited | RControllerIntroUI | false |
让凝视事件控制 LControllerIntroUI
- 01
选中 Left Controller 并找到 Callout Gaze Controller。
- 02
在 Facing Entered 中添加 LControllerIntroUI。
- 03
选择 GameObject > SetActive(bool),勾选参数表示 true。
- 04
在 Facing Exited 中再次添加 LControllerIntroUI。
- 05
选择相同方法,不勾选参数表示 false。
- 06
对 Right Controller 重复操作,但控制对象改为 RControllerIntroUI。
- 07
最后把两套 UI 根对象设置为初始停用。

观察布尔参数:Entered 已勾选,Exited 未勾选。截图中的界面对象名可能与本课命名不同,请选择自己的 LControllerIntroUI 或 RControllerIntroUI。
七个运行场景
按顺序验证初始状态、左右独立显示、移开隐藏和快速移动保护。
左右滑动表格,可查看完整内容
| 操作 | 预期结果 |
|---|---|
| 没有看向手柄 | 两套界面都隐藏 |
| 只看向左手柄 | 左侧四个标签显示,右侧保持隐藏 |
| 移开左手柄 | 左侧界面自动隐藏 |
| 只看向右手柄 | 右侧四个标签显示,A 键附近显示“跳跃” |
| 两只手柄靠得很近 | 可能分别进入凝视范围,必要时微调阈值 |
| 快速挥动手柄 | 立即隐藏,稳定后重新看向可以显示 |
| 观察 TriggerTip | “UI交互”完整显示,不被截断 |
常见现象与处理方法
优先检查对象、事件参数和界面设置,再调整凝视阈值。
左右滑动表格,可查看完整内容
| 现象 | 优先确认 | 处理方法 |
|---|---|---|
| 看向手柄完全不显示 | 组件、Gaze Transform、Entered 事件 | 确认对象与 true 参数 |
| 进入场景就一直显示 | UI 初始状态与 Exited 事件 | 初始停用,Exited 使用 false |
| 隐藏后再也无法显示 | 是否关闭了 Controller | 只控制 UI 根对象 |
| 圆角横向拉伸变形 | Border 与 Sliced | 应用边界并使用 Sliced |
| 文字模糊 | 画布缩放与动态像素密度 | 先确认观察距离,再调整到约 5 |
| UI交互显示不完整 | TriggerTip 宽度与文字锚点 | 加宽背景并使用双向拉伸 |
| 移动时不断闪烁 | 移动阈值与冷却时间 | 先恢复 0.05 与 0.25 |
| 左右说明经常同时显示 | Facing Threshold 过低 | 提高到约 0.949 后重试 |
从凝视组件到两套界面完整串联
独立完成左右凝视、两张画布、八个标签和四条事件映射。
- 左右 Controller 各有一个凝视组件,并使用同一个 Gaze Interactor。
- 阈值约为 0.949,移动距离为 0.05,冷却时间为 0.25。
- 每只手柄下各有一张 World Space 画布和四个标签。
- 圆角背景具有 Border 并使用 Sliced。
- 文字锚点、像素倍率和动态像素密度设置正确。
- 左 X 显示“菜单”,右 A 显示“跳跃”。
- Entered 显示对应 UI,Exited 隐藏对应 UI。
- 两套 UI 初始隐藏,Controller 始终保持启用。
- 七个运行场景全部得到预期结果。
本课成果清单
结束运行前逐项确认两套说明界面已经完整工作。
- 能够区分 Controller 与 Hand,并说明组件为什么挂在 Controller。
- 左右 Gaze Transform 都指向 Gaze Interactor。
- 两张画布都是对应 Controller 的 World Space 子对象。
- 八个标签的对象名、按键位置和文字正确。
- 圆角背景拉伸后没有明显变形。
- 文字在正常观察距离清楚,UI交互没有被截断。
- 两套 UI 初始隐藏,左右事件不会互相串联。
- 看向时显示、移开时隐藏、快速移动时先隐藏。
- MainScene 已保存,Console 没有新增错误。
把知识变成作品
本课练习
请按顺序完成以下任务,并保存自己的学习成果。- 01
不用查看表格,指出左右手柄四类按键并说出当前项目功能。
- 02
沿架构图说明 Gaze Interactor、左右 Controller、事件和说明界面的关系。
- 03
比较 0.85 与 0.949 两个阈值,预测两只手柄同时显示的可能性。
- 04
重新制作一个能够横向拉伸且圆角不变形的标签背景。
- 05
故意把右 PrimaryTip 保留为“菜单”,再根据按键映射找出并修正。
- 06
故意关闭 Left Controller,观察无法重新显示的原因,再改为只控制 LControllerIntroUI。
把本课进度保存下来
登录后可以保存浏览内容、有效学习时间、完成状态和答题参与记录。