场景可选对象(Scene Selectables)(Pro)
场景选择(Scene Selection)系统提供交互式运行时对象选择,具有复杂的视觉反馈,允许操作员在虚拟调试、培训和调试场景中检查组件、查看实时信号状态并与仿真元素交互。

概述
场景选择将静态 3D 模型转换为交互式元素,用户可以在运行时悬停、点击和检查。系统提供多层视觉反馈,分别为悬停效果、活动状态、选择和更改指示器提供独立的高亮显示。每个可选对象可以在悬停时显示工具提示,在点击时显示详细信息窗口,包括可以直接从界面切换的实时信号状态。
关键功能包括:
- 多层高亮系统,具有四个独立的视觉状态(活动、悬停、已选择、已更改)
- 交互式工具提示,在悬停时出现,具有可自定义的内容
- 详细选择窗口,显示属性、描述和实时信号状态
- 信号监控和控制,带有实时操作的切换开关
- 更改追踪,当对象的信号状态与初始值不同时高亮显示
- 动态内容系统,用于添加运行时值和可点击链接
- 多渲染器分组,将复杂模型视为单个可选单元
- 基于射线检测的交互,具有自动 UI 回避功能
该系统与 realvirtual 的信号系统无缝集成,允许您直接从选择界面监控和控制 PLCInputBool、PLCOutputBool 和其他信号类型。这对于调试自动化逻辑、培训操作员操作设备功能以及创建交互式维护程序非常有价值。
设置和配置
将场景选择添加到您的场景
在您的项目中实现场景选择:
- 添加预制件:将
SceneSelectables预制件从Assets/realvirtual/UIPrefabs/拖入场景层级 - 配置工具栏按钮:系统使用 SceneSelectionManager 中指定的图标自动添加工具栏按钮
- 设置高亮管理器:预制件预配置了四个自动检测的高亮管理器:
- Highlight 1:活动状态高亮
- Highlight 2:悬停效果高亮
- Highlight 3:更改状态高亮
- Highlight 4:选择状态高亮
创建可选对象
您可以通过两种方式创建可选对象:
方法 1:使用添加可选对象按钮
- 在层级中选择 SceneSelectables 游戏对象
- 在检视器中点击添加可选对象(Add Selectable)
- 新的 SceneSelectable 子对象会自动创建
- 在检视器中配置可选对象的属性
方法 2:手动创建
- 创建空游戏对象作为 SceneSelectables 的子对象
- 添加 SceneSelectable 组件
- 配置渲染器、信号和内容
SceneSelectionManager 属性
SceneSelectionManager 协调所有选择交互和视觉反馈:
选择管理器
活动(Active)(AbstractSelectionManager)控制处于默认活动状态的对象的高亮。此管理器在选择系统启用时对所有可选对象应用视觉反馈,为指示哪些对象可交互提供基础层高亮。
悬停(Hover)(AbstractSelectionManager)管理鼠标光标移到可选对象上时的悬停效果。这为用户提供即时视觉反馈,指示如果点击将选择哪个对象。光标移开后悬停高亮会自动移除。
已选择(Selected)(AbstractSelectionManager)处理被点击和选择对象的持久高亮。此高亮保持活动直到选择另一个对象或清除选择,提供当前检查对象的清晰视觉指示。
已更改(Changed)(AbstractSelectionManager)高亮信号状态与初始值不同的对象。这对于调试和培训场景特别有用,因为它立即显示哪些组件在仿真期间已被操作或已更改状态。
UI 配置
图标(Icon)(Sprite)定义启用/禁用选择系统的工具栏按钮图标。此图标在工具栏按钮的开启和关闭状态中都显示,为选择工具提供一致的视觉标识。
窗口(Window)(GameObject)引用在选择对象时显示详细信息的窗口预制件。此窗口包含标题、描述、信号切换开关和与所选对象关联的任何动态内容。
标题(Title)(TextMeshProUGUI)指向在选择窗口标题中显示所选对象标题的文本组件。选择对象时自动更新。
描述(Description)(GameObject)包含显示详细描述的面板。面板根据所选对象是否定义了描述自动显示或隐藏。
工具提示(Tooltip)(GameObject)引用在悬停时出现的工具提示预制件。工具提示自动调整大小以适应内容并跟随鼠标光标位置。
UI 预制件
值预制件(Value Prefab)(GameObject)定义在选择窗口中显示属性值的模板。此预制件为每个值类型内容项实例化,显示标签和值对。
按钮预制件(Button Prefab)(GameObject)提供在选中窗口中创建交互式链接按钮的模板。这些按钮可以打开 URL、文档或在点击时触发其他操作。
SceneSelectable 属性
基本信息
标题(Title)(字符串)设置选择窗口标题中显示的文本。这应该是一个清晰、简洁的名称,用于标识被选择的组件或系统。例如:"传送带电机 M1"或"安全门传感器"。
描述(Description)(字符串)提供有关所选对象的详细信息。此文本在选择窗口的可展开面板中显示,可以包含操作详情、规格或使用说明。如果未提供文本,描述面板会自动隐藏。
工具提示(Tooltip)(字符串)定义鼠标光标悬停在对象上时出现的文本。工具提示通过检视器中的自定义文本区域编辑,支持多行内容。使用工具提示提供快速识别或状态信息,无需完全选择。
视觉配置
渲染器(Renderers)(列表)指定属于此可选单元的所有网格渲染器。当列表中的任何渲染器被悬停或选择时,所有渲染器一起高亮。这允许您将复杂模型的多个部分分组为单个交互式元素。例如,电机组件可能包括电机本体、安装支架和冷却风扇作为单独的渲染器,以一个单元高亮。
信号集成
信号(Signals)(列表)包含通过选择窗口监控和控制的信号。每个信号在选择窗口中显示为切换开关,显示其当前状态并允许直接操作。系统追踪所有信号的初始状态,并在值与起始状态不同时自动应用更改高亮。支持的信号类型包括:
- PLCInputBool 用于输入信号
- PLCOutputBool 用于输出信号
- PLCInputFloat 和 PLCOutputFloat 用于模拟信号
- 自定义信号实现
动态内容
内容(Contents)(列表)存储在选择窗口中显示的附加信息项。每个内容项可以是值(文本显示)或链接(可点击按钮)。使用 AddStringContent 和 AddLinkContent 方法通过编程添加内容项,允许您使用运行时数据填充选择窗口。
使用示例
基本设置示例
以下是如何设置简单的可选传送带电机:
// 在检视器中配置或通过脚本
SceneSelectable motorSelectable = conveyorMotor.AddComponent<SceneSelectable>();
motorSelectable.SetTitle("Conveyor Drive Motor M1");
motorSelectable.description = "Main drive motor for conveyor section 1\n" +
"Power: 5.5 kW\n" +
"Speed: 0-1450 RPM";
motorSelectable.tooltip = "Motor M1 - Click for details";
// 添加电机的网格渲染器
motorSelectable.renderers.Add(motorBody.GetComponent<MeshRenderer>());
motorSelectable.renderers.Add(motorFan.GetComponent<MeshRenderer>());
// 链接电机控制信号
motorSelectable.signals.Add(motorRunSignal);
motorSelectable.signals.Add(motorFaultSignal);
motorSelectable.signals.Add(motorSpeedSignal);
添加动态内容
您可以为可选对象添加运行时信息:
public class MotorMonitor : MonoBehaviour
{
private SceneSelectable selectable;
private float runtime = 0;
void Start()
{
selectable = GetComponent<SceneSelectable>();
// 添加静态信息
selectable.AddStringContent("Serial Number", "MTR-2024-0156");
selectable.AddStringContent("Installation Date", "2024-03-15");
// 添加文档链接
selectable.AddLinkContent("View Manual",
"https://doc.realvirtual.io/motors/m1-series");
// 添加维护链接
selectable.AddLinkContent("Maintenance Schedule",
"https://maintenance.local/motor/M1");
}
void Update()
{
runtime += Time.deltaTime;
// 更新运行时显示
selectable.ClearContent();
selectable.AddStringContent("Runtime",
$"{runtime:F1} hours");
selectable.AddStringContent("Temperature",
$"{GetMotorTemp():F1}°C");
}
}
工具提示配置
工具提示通过自定义检视器界面配置:
- 选择一个 SceneSelectable 对象
- 在检视器中,在底部找到工具提示(Tooltip)部分
- 在文本区域中输入多行工具提示文本
- 工具提示在运行时悬停时自动出现
示例工具提示内容:
Safety Door SD-01
Status: Closed
Interlock: Active
Last opened: 10:45 AM
信号监控示例
以下展示选择系统如何与传感器信号集成:
public class SensorSelectable : MonoBehaviour
{
public PLCInputBool sensorActive;
public PLCInputBool sensorFault;
public PLCOutputBool sensorReset;
void Start()
{
SceneSelectable selectable = GetComponent<SceneSelectable>();
// 添加监控信号
selectable.signals.Add(sensorActive);
selectable.signals.Add(sensorFault);
selectable.signals.Add(sensorReset);
// 设置描述性标题
selectable.SetTitle($"Proximity Sensor {gameObject.name}");
// 添加诊断信息
selectable.AddStringContent("Type", "Inductive");
selectable.AddStringContent("Range", "8mm");
selectable.AddStringContent("Output", "PNP NO");
}
}
高级功能
多层高亮系统
四层高亮系统提供复杂的视觉反馈:
- 基础层(活动):在选择系统启用时显示所有交互式对象
- 悬停层:在光标移动时提供即时反馈
- 选择层:保持显示当前检查的对象
- 更改层:叠加显示已修改的对象
这些层共同创建直观的交互体验。例如,电机可能显示:
- 活动高亮(蓝色轮廓)指示可选
- 悬停高亮(黄色发光)当鼠标在对象上时
- 选择高亮(绿色轮廓)当点击时
- 更改高亮(红色脉冲)如果其信号已被切换
更改追踪
系统自动追踪信号更改:
// 初始状态在 Start() 时自动捕获
// 当信号更改时,Changed 高亮管理器激活
// 这自动发生 - 无需代码
// 以编程方式重置更改追踪:
void ResetChangeTracking()
{
SceneSelectionManager manager = FindObjectOfType<SceneSelectionManager>();
manager.RefreshActives(); // 重新评估所有更改状态
}
自定义选择行为
您可以通过响应选择事件来扩展选择行为:
public class CustomSelectable : MonoBehaviour
{
private SceneSelectable selectable;
void Start()
{
selectable = GetComponent<SceneSelectable>();
}
void Update()
{
// 检查此对象当前是否被选中
SceneSelectionManager manager =
GetComponentInParent<SceneSelectionManager>();
if (manager.selectedSelectable == selectable)
{
// 在选中时执行操作
UpdateRealtimeData();
}
}
void UpdateRealtimeData()
{
// 在选中时更新动态内容
selectable.ClearContent();
selectable.AddStringContent("Speed",
$"{GetCurrentSpeed():F1} m/s");
selectable.AddStringContent("Position",
$"{transform.position}");
}
}
编程式选择控制
您可以通过代码控制系统选择:
public class SelectionController : MonoBehaviour
{
private SceneSelectionManager selectionManager;
void Start()
{
selectionManager = FindObjectOfType<SceneSelectionManager>();
}
public void EnableSelection()
{
selectionManager.Activate();
}
public void DisableSelection()
{
selectionManager.Deactivate();
}
public void ClearSelection()
{
selectionManager.CloseWindow();
}
public void RefreshHighlighting()
{
selectionManager.RefreshActives();
}
}
API 参考
SceneSelectionManager 方法
Activate() 启用所有子 SceneSelectable 组件并应用初始高亮。调用此方法以编程方式打开选择系统。
Deactivate() 禁用所有子 SceneSelectable 组件,移除高亮并关闭任何打开的窗口。使用此方法关闭选择系统。
RefreshActives() 根据当前信号值重新评估所有可选对象的活动/更改状态。这会更新高亮以反映自初始化以来的任何更改。
CloseWindow() 关闭当前选择窗口并清除选择高亮。所选对象的引用也被清除。
AddSelectable() 创建新的 SceneSelectable 子游戏对象。此编辑器方法提供通过检视器快速添加可选对象的方式。
SceneSelectable 方法
SetTitle(string title) 设置选择窗口标题的显示标题。
AddStringContent(string name, string value) 向选择窗口添加文本值显示。name 显示为标签,value 在旁边显示。
AddLinkContent(string name, string url) 添加一个可点击按钮,打开指定的 URL。用于文档链接、外部资源或基于 Web 的工具。
ClearContent() 移除所有动态添加的内容项。信号显示不受影响。
Activate() 启用此可选对象,创建必要的 SelectablePart 组件并应用初始高亮。
Deactivate() 禁用此可选对象,移除 SelectablePart 组件并清除所有高亮。
Hover() 对所有关联的渲染器应用悬停高亮,并显示工具提示(如果已配置)。
UnHover() 移除悬停高亮并隐藏工具提示。
Click() 处理选择,切换选择状态并打开或关闭信息窗口。
HasTooltip() 如果为此可选对象配置了工具提示则返回 true。
RefreshActive(SceneSelectionManager manager) 根据当前信号值与初始状态比较来更新视觉状态。
SceneSelectableContent 结构
SceneSelectableContent 类定义附加信息项:
public class SceneSelectableContent
{
public enum Type
{
Value, // 文本显示
Link // 可点击 URL 按钮
}
public Type type; // 内容类型
public string name; // 显示标签
public string value; // 文本或 URL
}
性能考虑
射线检测优化
系统使用 Physics.RaycastAll 进行准确的多层检测。为优化性能:
- 将可选对象放在特定层上
- 在物理设置中使用层遮罩排除不必要的对象
- 在密集场景中限制活动可选对象的数量
高亮性能
每个高亮管理器都会影响渲染性能:
- 使用简单的轮廓着色器以获得更好的性能
- 限制同时高亮效果的数量
- 考虑复杂模型的 LOD 设置
- 为摄像机视图外的对象禁用高亮
信号更新
信号监控在运行时持续进行:
- 限制每个可选对象的信号数量(建议 < 10)
- 使用高效的信号实现
- 考虑实时数据的更新频率
- 缓存信号引用以避免查找
Unity 6 兼容性
将项目升级到 Unity 6 时,必须禁用 Render Graph 兼容模式才能使高亮正确工作:
- 打开编辑 > 项目设置(Edit > Project Settings)
- 导航到图形(Graphics)
- 找到渲染图设置(Render Graph Settings)
- 禁用兼容模式(Compatibility Mode)
- 重启 Unity 编辑器

此设置确保高亮着色器在 Unity 6 的渲染管线中正确工作。
CMCViewR 兼容性
将 realvirtual 项目部署到 CMCViewR 时,场景可选对象有以下限制:
场景可选对象不受支持
场景可选对象不兼容 CMCViewR,在导出的 CMCViewR 场景中将不起作用。交互式选择系统、高亮、工具提示和选择窗口是编辑器/运行时 Unity 功能,不会转换到 CMCViewR 环境。
如果您需要在 CMCViewR 中进行交互式对象选择,需要实现与 CMCViewR 运行时兼容的替代交互方法。
自定义脚本要求
在将导出到 CMCViewR 的项目中使用自定义脚本时,所有自定义代码必须放在其自己的自定义程序集定义中。这是 CMCViewR 对正确脚本编译和部署的要求。
为您的脚本创建自定义程序集定义:
- 创建新文件夹用于自定义脚本(例如,
Assets/CustomScripts/) - 在文件夹中右键单击并选择创建 > 程序集定义(Create > Assembly Definition)
- 命名程序集(例如,
MyProject.Custom) - 在程序集定义检视器中:
- 添加对
realvirtual和其他所需程序集的引用 - 根据需要配置平台兼容性
- 将所有自定义脚本放在此文件夹中
- 添加对
示例程序集定义设置:
{
"name": "MyProject.Custom",
"references": [
"realvirtual.base",
"Unity.TextMeshPro"
],
"includePlatforms": [],
"excludePlatforms": []
}
摄像机处理
导出到 CMCViewR 时,您不需要手动准备或禁激活 realvirtual 摄像机。当场景在 CMCViewR 中运行时,realvirtual 摄像机系统将自动禁激活,因为 CMCViewR 使用其自己的摄像机管理系统。
与其他组件的集成
场景选择与其他 realvirtual 组件无缝集成:
驱动器集成
可选驱动器可以显示当前位置、速度和控制信号:
selectable.signals.Add(drive.JogForward);
selectable.signals.Add(drive.JogBackward);
selectable.AddStringContent("Position", $"{drive.CurrentPosition:F2} mm");
传感器集成
传感器可以显示检测状态和配置:
selectable.signals.Add(sensor.Occupied);
selectable.AddStringContent("Detection Range", $"{sensor.Range} mm");
传输系统集成
传送带和传输系统受益于调试选择:
selectable.signals.Add(conveyor.Running);
selectable.signals.Add(conveyor.EmergencyStop);
selectable.AddStringContent("Speed", $"{conveyor.Speed:F1} m/s");
故障排除
高亮不显示
- 验证 Render Graph Compatibility Mode 已禁用(Unity 6)
- 检查高亮管理器是否在 SceneSelectionManager 中分配
- 确保渲染器具有支持高亮着色器的材质
- 验证 Highlighter 预制件存在于场景层级中
工具提示不出现
- 检查工具提示文本是否在检视器中配置
- 验证 Tooltip GameObject 是否在 SceneSelectionManager 中分配
- 确保场景中存在 EventSystem 用于 UI 交互
- 检查 Canvas 渲染模式是否支持世界空间工具提示
信号不更新
- 验证信号在添加到可选对象之前是否正确初始化
- 检查信号游戏对象在层级中是否活动
- 确保 PLCInterface 或信号源正在运行
- 验证信号引用不为 null
选择窗口问题
- 检查 Window GameObject 是否在 SceneSelectionManager 中分配
- 验证 UI Canvas 和 EventSystem 是否存在
- 确保窗口预制件具有所需的组件(RectTransform、CanvasGroup)
- 检查文本组件是否使用 TextMeshPro
最佳实践
- 分组相关渲染器:将同一组件的部分合并为单个可选对象,以获得更清晰的交互
- 使用描述性标题:使标题清晰并包含标识信息(例如,"Motor M1"而不是仅"Motor")
- 提供有用的工具提示:在工具提示中包含状态信息,以便在选择前快速检查
- 限制信号数量:保持信号列表专注于最相关的控制(最多 5-10 个信号)
- 添加上下文链接:包含文档、数据表或维护程序的链接
- 谨慎更新动态内容:仅在选中时更新运行时值以减少开销
- 使用一致的高亮:在应用程序中为每个高亮状态保持一致的颜色
- 测试性能:在复杂场景中分析选择交互并根据需要进行优化
另请参见
- 信号(Signals) - PLC 通信的信号系统
- UI 系统(UI System) - 用户界面组件和控件
- 高亮系统(Highlighting System) - 视觉反馈和高亮
- 驱动器(Drive) - 与选择集成的驱动器组件
- 传感器(Sensor) - 用于检测和监控的传感器组件