第 08 课
实现高亮轮廓效果
本课将为可抓取文物增加高亮轮廓。当手柄射线或近距离交互器指向文物时,轮廓自动出现;当最后一个交互器离开时,轮廓自动消失。
让文物在被指向时清楚回应
使用轮廓高亮告诉体验者“当前文物可以操作”,再通过首次悬停与最后离开事件,让轮廓在正确时机出现和消失。
学完你将能够
学习目标
- 解释视觉反馈为什么能够降低虚拟现实操作中的不确定感。
- 区分悬停、选择、焦点和激活四种常见交互状态。
- 从资源商店获取轮廓工具,并将它导入当前项目。
- 为包含多个子物体的文物正确添加和配置轮廓组件。
- 根据场景遮挡关系选择轮廓模式、颜色和宽度。
- 使用首次悬停与最后离开事件控制轮廓显示。
- 把同一效果应用到其他文物,并解决轮廓不完整或对象引用错误。
开始操作前
准备工作
- 打开上一课保存的主场景,确认三个文物都可以通过近距离接触和远距离射线抓取。
- 确认文物顶层对象具有 XR Grab Interactable,也就是“可抓取组件”。
- 确认文物碰撞体覆盖模型主体,左右手都能使文物进入悬停状态。
- 确认 Unity 编辑器能够联网,并已登录自己的 Unity 账号。
- 保存当前场景,再开始导入资源和配置轮廓。
本课学习路线
按照学习模块逐步完成
每个模块都包含理解、跟随操作和独立实践。先理解系统应该在何时回应
认识视觉反馈与交互状态
在按下抓取键之前,体验者就需要知道手柄是否已经找到目标。高亮轮廓正是在这个阶段提供确认。为什么虚拟现实交互需要视觉反馈
现实中的按钮会产生回弹,物体会移动或发出声音,这些变化能帮助我们判断操作是否成功。虚拟物体通常没有真实触感,如果画面毫无变化,体验者就无法确定射线是否指到目标、文物是否可以抓取。
视觉反馈通过颜色、轮廓、亮度、缩放或动画告诉体验者:系统已经识别当前动作,下一步操作可以继续。
一次交互中的反馈循环
每个阶段都应该回答体验者当前最关心的问题。
左右滑动表格,可查看完整内容
| 阶段 | 体验者的行为或判断 | 系统应该提供的信息 |
|---|---|---|
| 发现 | 看到场景中的文物 | 哪些对象可能可以操作 |
| 指向 | 手或射线接近文物 | 当前目标已经被识别 |
| 操作 | 按下抓取键 | 抓取已经开始 |
| 结束 | 松开或移开手柄 | 对象已经释放或不再是当前目标 |
交互器与可交互对象
反馈发生在主动方和目标对象之间。
左右滑动表格,可查看完整内容
| 名称 | 中文理解 | 本项目中的例子 |
|---|---|---|
| Interactor | 交互器,负责发现和发起交互 | 左手、右手和手柄射线 |
| Interactable | 可交互对象,负责接收交互 | 已经可以抓取的文物 |
四种常见交互状态
本课使用悬停状态显示轮廓,其他状态将在后续交互中继续使用。
左右滑动表格,可查看完整内容
| 状态 | 中文理解 | 本项目中的表现 | 适合的反馈 |
|---|---|---|---|
| Hover | 悬停:已经指向或接近,但还没有正式操作 | 射线落在文物上,或手进入交互范围 | 显示轮廓、改变颜色或显示提示 |
| Select | 选择:已经开始操纵对象 | 按住抓取键并拿起文物 | 抓取动画、声音或手柄提示 |
| Focus | 焦点:系统把对象标记为当前关注目标 | 交互组优先处理某件文物 | 保存当前目标或决定后续逻辑 |
| Activate | 激活:对已选择对象执行进一步操作 | 抓住工具后按下功能键 | 开火、启动工具或打开功能 |
观察手柄已有的状态提示
- 01
运行场景,选择右手柄。
- 02
把射线移到空白区域,观察射线或前端提示点的颜色。
- 03
把射线移到可抓取文物上,观察提示变化。
- 04
按住抓取键,再观察进入选择状态后的变化。
- 05
移到不可交互模型上进行比较。
用左右手判断悬停开始和结束
分别指向、移开、抓取和释放一个文物,并用自己的话描述状态变化。
- 能够指出悬停从什么时候开始。
- 能够指出悬停在什么时候结束。
- 能够区分悬停和正式抓取。
- 能够说明为什么轮廓应该在按下抓取键之前出现。
把需要的功能加入当前项目
获取并导入轮廓工具
本课使用 Quick Outline,也就是“快速轮廓”工具。它可以直接添加到三维模型上,并通过组件启用状态显示或隐藏轮廓。为什么使用快速轮廓工具
Quick Outline 能为三维模型绘制实体轮廓,并提供多种显示模式、颜色和宽度设置。它支持虚拟现实常用的立体渲染方式,也可以直接与可抓取组件的交互事件连接。
本课先在属性窗口中完成配置,不额外编写程序,把注意力集中在交互状态、轮廓外观和事件连接上。
在资源商店中找到正确工具
- 01
打开 Unity 资源商店。
- 02
在搜索框输入 Quick Outline。
- 03
在搜索结果中找到名称为 Quick Outline、发布者为 Chris Nolet 的工具。
- 04
打开资源详情,阅读价格、许可、支持版本和兼容说明。
- 05
使用与 Unity 编辑器相同的账号登录,并把资源添加到自己的资源库。

搜索结果中可能出现多个轮廓工具。请根据名称、发布者和预览图确认本课使用的 Quick Outline。
点击图片可以查看完整截图选择工具时要阅读的信息
不要只看效果图片,还要判断它能否适应当前项目。
左右滑动表格,可查看完整内容
| 信息 | 为什么重要 |
|---|---|
| 虚拟现实支持 | 只适用于普通屏幕的轮廓效果,在头戴设备中可能显示异常 |
| Unity 版本 | 版本跨度过大时,工具接口和渲染方式可能发生变化 |
| 渲染管线 | 不同渲染管线使用的着色器并不完全通用 |
| 最近版本 | 帮助判断工具是否仍在维护 |
| 许可方式 | 决定能否用于自己的项目和发布作品 |
| 使用说明 | 提前了解组件、参数和常见问题 |
在包管理器中下载并导入
- 01
回到 Unity 编辑器,打开 Window → Package Manager,也就是“窗口 → 包管理器”。
- 02
把左上角的资源分类切换为 My Assets,也就是“我的资源”。
- 03
搜索 Quick Outline 并选中结果。
- 04
尚未下载时先点击 Download,也就是“下载”。
- 05
下载完成后点击 Import,也就是“导入”。
- 06
在导入窗口中保留需要的文件,再次确认导入。

包管理器需要切换到“我的资源”。右上角的 Import 会把已经下载的工具文件加入当前项目。
点击图片可以查看完整截图确认轮廓工具已经可用
完成导入后,在任意游戏对象的添加组件搜索框中查找 Outline。
- 项目窗口中出现 QuickOutline 工具文件夹。
- 工具脚本和材质文件完整存在。
- 在 Add Component 中能够搜索到 Outline。
让轮廓清楚但不过度遮挡文物
配置文物的轮廓外观
先让第一个文物静态显示轮廓,确认组件位置、显示模式、颜色、宽度和预计算都正确,再把轮廓恢复为初始隐藏。轮廓组件应该添加在顶层父对象
Outline 是“轮廓组件”。它会查找当前对象及子对象中的渲染器,为模型准备轮廓需要的数据和材质。
多部件文物应把组件添加到代表整件文物的顶层父对象。只添加到某个子物体时,可能只有局部模型出现轮廓,交互事件与轮廓组件也更容易分散在不同对象上。
添加并初步设置轮廓组件
- 01
在层级窗口中选择文物的顶层父对象。
- 02
点击 Add Component,搜索并添加 Outline。
- 03
暂时保持组件启用,以便立即观察轮廓外观。
- 04
先选择 Outline All,也就是“全部轮廓”。
- 05
设置容易识别的颜色,把宽度从 2 到 3 开始尝试。
- 06
启用 Precompute Outline,也就是“预先计算轮廓”。

先观察模式、颜色和宽度。预先计算可以减少复杂模型在运行开始时临时计算轮廓数据的工作量。
点击图片可以查看完整截图五种轮廓显示模式
模式决定可见部分和被遮挡部分怎样显示。
左右滑动表格,可查看完整内容
| 模式 | 显示规则 | 适合场景 | 需要注意 |
|---|---|---|---|
| Outline All 全部轮廓 | 无论模型是否被遮挡都显示 | 当前可操作文物和任务目标 | 隔着墙也可能看到完整轮廓 |
| Outline Visible 可见部分轮廓 | 只显示当前直接可见部分 | 强调真实遮挡关系的展览场景 | 被遮挡部分不会显示 |
| Outline Hidden 隐藏部分轮廓 | 只显示被遮挡部分 | 提示墙后或遮挡物后的目标 | 直接可见部分没有普通轮廓 |
| Outline And Silhouette 轮廓加剪影 | 可见部分显示轮廓,被遮挡部分显示纯色 | 需要强烈标记的任务目标 | 提示较强,可能削弱真实感 |
| Silhouette Only 仅剪影 | 只强调被遮挡部分的纯色剪影 | 显示隐藏目标的位置 | 不适合普通文物的轻量悬停提示 |
轮廓外观参数
最终效果要在头戴设备中观察,不能只根据编辑器画面判断。
左右滑动表格,可查看完整内容
| 参数 | 作用 | 设置建议 |
|---|---|---|
| Outline Color | 决定轮廓颜色 | 选择与文物和背景对比明显、又不会被误解为警告的颜色 |
| Outline Width | 决定轮廓线粗细 | 从 2 到 3 开始,避免过粗遮挡文物细节 |
| Precompute Outline | 提前计算部分轮廓数据 | 复杂模型建议启用,修改或重新导入模型后再次观察 |
先确认静态轮廓,再设置初始隐藏
- 01
保持 Outline 启用并运行场景。
- 02
确认轮廓覆盖完整文物,颜色和宽度清楚可见。
- 03
从遮挡物后观察,判断当前模式是否符合场景需要。
- 04
停止运行,取消勾选 Outline 组件标题左侧的启用框。
- 05
再次运行,确认文物启动时不再自动显示轮廓。
为第一个文物确定轮廓风格
比较至少两种模式和两组宽度,选择清楚又不过度遮挡文物的组合。
- 轮廓组件位于文物顶层父对象。
- 静态启用时,轮廓覆盖整件文物。
- 颜色与背景和文物本身具有足够对比。
- 宽度不会明显遮挡文物细节。
- 完成外观设置后,组件恢复为禁用状态。
第一只手进入时显示,最后一只手离开时隐藏
用悬停事件控制轮廓
可抓取组件会在交互状态变化时发出事件。本课把首次悬停事件连接到轮廓启用,把最后离开事件连接到轮廓禁用。把交互状态转换成事件
当交互器开始悬停、结束悬停、开始抓取或结束抓取时,可抓取组件都会发出对应事件。这些事件可以直接连接到其他组件的属性,不一定需要编写新程序。
Outline.enabled 表示“轮廓组件是否启用”。True 表示启用,False 表示禁用。
本课的事件连接
两个事件共同形成完整的显示与隐藏逻辑。
左右滑动表格,可查看完整内容
| 条件 | 执行动作 | 结果 |
|---|---|---|
| 第一只手开始悬停 | 把 Outline.enabled 设置为 True | 显示轮廓 |
| 最后一只手结束悬停 | 把 Outline.enabled 设置为 False | 隐藏轮廓 |
普通悬停事件与首次/最后悬停事件
轮廓关心的是“是否还有任意一只手在指向文物”,因此使用首次/最后事件。
左右滑动表格,可查看完整内容
| 事件组 | 触发方式 | 适合处理 |
|---|---|---|
| Hover Entered / Hover Exited | 每个交互器进入或离开时都会触发 | 分别记录每只手的行为 |
| First Hover Entered / Last Hover Exited | 第一只交互器进入时触发一次,最后一只离开时再触发 | 判断文物整体是否仍被任意交互器悬停 |
双手悬停时的轮廓状态
其中一只手离开时,另一只手仍然需要获得反馈。
左右滑动表格,可查看完整内容
| 顺序 | 发生的动作 | 首次/最后事件 | 轮廓状态 |
|---|---|---|---|
| 1 | 右手进入 | 触发首次进入 | 显示 |
| 2 | 左手也进入 | 不重复触发首次进入 | 保持显示 |
| 3 | 右手离开,左手仍在 | 不触发最后离开 | 保持显示 |
| 4 | 左手最后离开 | 触发最后离开 | 隐藏 |
配置首次悬停时显示轮廓
- 01
选择文物顶层父对象,确认 Outline 组件初始处于禁用状态。
- 02
找到 XR Grab Interactable,展开 Interactable Events。
- 03
展开 First/Last Hover。
- 04
在 First Hover Entered 下点击加号。
- 05
把当前文物的顶层父对象拖入事件对象栏。
- 06
在函数列表中选择 Outline → bool enabled。
- 07
勾选参数复选框,把值设置为 True。

事件对象必须是当前文物自身。首次进入事件选择 Outline 的 enabled 属性,并把参数勾选为 True。
点击图片可以查看完整截图配置最后一只手离开时隐藏轮廓
- 01
在 Last Hover Exited 下点击加号。
- 02
再次把当前文物的顶层父对象拖入事件对象栏。
- 03
选择 Outline → bool enabled。
- 04
不要勾选参数复选框,让值保持为 False。
- 05
保存场景。
两个事件的参数不能相同
进入时启用,离开时禁用。
左右滑动表格,可查看完整内容
| 事件 | enabled 参数 | 结果 |
|---|---|---|
| First Hover Entered | True,勾选 | 显示轮廓 |
| Last Hover Exited | False,不勾选 | 隐藏轮廓 |
用单手和双手验证完整反馈
按照固定顺序验证,确保轮廓反映文物整体的悬停状态。
- 程序启动后,不触碰文物时轮廓保持隐藏。
- 右手射线移入时显示,移出时隐藏。
- 左手单独悬停也能显示轮廓。
- 左右手同时悬停,其中一只手离开后轮廓仍然显示。
- 最后一只手离开后轮廓立即隐藏。
- 抓取、移动和释放功能保持正常。
统一反馈风格,保持每件文物独立
应用到其他文物并处理异常
轮廓外观可以复制,但每件文物的事件必须引用自己。复杂模型出现轮廓缺失时,再根据网格结构和读取权限逐步处理。把轮廓外观复制到另外两个文物
- 01
打开第一个文物的 Outline 组件菜单,选择 Copy Component,也就是“复制组件”。
- 02
选择第二个文物的顶层父对象。
- 03
选择 Paste Component As New,也就是“粘贴为新组件”。
- 04
确认模式、颜色、宽度、预计算和初始禁用状态都已复制。
- 05
对第三个文物重复以上操作。
每个文物都要连接自己的事件
复制外观后,逐个设置事件对象。
左右滑动表格,可查看完整内容
| 事件 | 事件对象 | 调用属性 | 参数 |
|---|---|---|---|
| First Hover Entered | 当前文物自身 | Outline.enabled | True |
| Last Hover Exited | 当前文物自身 | Outline.enabled | False |
复杂模型为什么可能只显示部分轮廓
轮廓工具需要读取模型网格并准备平滑轮廓所需的数据。多网格子对象、大量顶点、不可读取的网格或被优化掉的数据,都可能造成轮廓缺失、断裂或位置偏移。
遇到问题时先确认 Outline 位于顶层父对象,再定位原始模型资源。只有确实需要运行时读取网格的模型,才启用 Read/Write Enabled,也就是“允许读取和写入”,因为它会增加内存占用。
轮廓不完整时按顺序处理
- 01
确认 Outline 添加在文物顶层父对象,而不是某个局部子物体。
- 02
从预制体定位到原始模型资源。
- 03
在模型导入设置中找到 Read/Write Enabled。
- 04
启用后点击 Apply,并确认 Precompute Outline 仍然开启。
- 05
重新运行并观察轮廓。
- 06
仍有偏移时,再根据实际情况查看网格数据优化设置,并在头戴设备中验证。
常见现象与处理方法
先根据现象找到相关设置,再重新验证。
左右滑动表格,可查看完整内容
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| 程序启动后轮廓一直显示 | Outline 初始仍处于启用状态 | 停止运行后禁用组件,再重新运行 |
| 射线指向文物但没有变化 | 没有进入悬停、事件对象错误或进入参数未勾选 | 依次确认碰撞体、交互层、首次进入事件和 True 参数 |
| 轮廓出现后无法消失 | 未配置最后离开,或离开参数仍为 True | 配置 Last Hover Exited,并把 enabled 设置为 False |
| 一只手离开后轮廓立即消失 | 误用了普通 Hover Exited | 改用 First Hover Entered 和 Last Hover Exited |
| 指向一个文物却点亮另一个 | 事件对象仍引用原来的文物 | 让每个事件引用当前文物自身 |
| 只有部分模型出现轮廓 | 组件层级错误、模型多网格或网格不可读取 | 移到顶层父对象,并按需启用模型读取与预计算 |
| 开始运行时出现短暂停顿 | 多个复杂模型同时计算轮廓数据 | 启用预计算,只给需要反馈的对象添加轮廓 |
本课成果清单
逐项确认后,三个文物就已经形成一致、稳定的高亮反馈。
- 三个文物启动时都不显示轮廓。
- 任意一只手首次悬停时,当前文物轮廓出现。
- 两只手同时悬停时,其中一只离开不会提前关闭轮廓。
- 最后一只手离开后,轮廓立即消失。
- 每件文物只控制自己的轮廓,抓取和释放功能保持正常。
- 轮廓完整、清楚,并且不会明显遮挡文物细节。
把知识变成作品
本课练习
请按顺序完成以下任务,并保存自己的学习成果。- 01
为一个尚未配置的文物独立完成轮廓组件、外观参数、初始隐藏和首次/最后悬停事件。
- 02
分别使用单手和双手完成悬停练习,观察其中一只手离开后轮廓是否保持,最后一只手离开后是否隐藏。
- 03
比较全部轮廓与可见部分轮廓两种模式,在头戴设备中选择更适合当前展馆遮挡关系的方案。
把本课进度保存下来
登录后可以保存浏览内容、有效学习时间、完成状态和答题参与记录。