边界控制 - MRTK2
BoundsControl 是先前在 BoundingBox 中发现的新操作行为组件。 边界控制在设置方面进行了大量改进和简化,并添加了新功能。 此组件是边界框的替换项,边界框将被弃用。
BoundsControl.cs
脚本提供用于在混合现实中转换对象的基本功能。 边界控制将在全息影像周围显示一个框,指示可以与之交互。 用框的角和边缘上的手柄可以缩放、旋转或转换对象。 边界控制也会对用户的输入做出反应。 例如,在 HoloLens 2 上,边界控制会在手指接近时作出反应,提供视觉反馈来帮助感知与对象的距离。 可以轻松自定义所有交互和视觉对象。
示例场景
可以在 BoundsControlExamples
场景中找到边界控制配置的示例。
检查器属性
“目标对象”
此属性指定边界控制操作将转换的对象。 如果不设置对象,则默认为所有者对象。
激活行为
有几个选项可激活边界控制界面。
- 启动时激活:在场景启动时,边界控制变为可见。
- 接近时激活:当明确有手接近对象时,边界控制变为可见。
- 通过指针激活:当边界控制成为手射线指针的目标时,边界控制变为可见。
- 通过邻近感应和指针激活:当边界控制成为手射线指针的目标,或在明确有手接近对象时,边界控制变为可见。
- 手动激活:边界控制不会自动变为可见。 可以通过访问 boundsControl.Active 属性,使用脚本手动激活它。
边界覆盖
从对象中设置框碰撞器以进行边界计算。
框填充
向用于计算控制范围的碰撞器边界添加填充。 这不仅会影响交互,还会影响视觉对象。
平展轴
指示控制是否平展到其中一个轴,使其成为二维的,并禁止沿该轴进行操作。 此功能可用于场记板等较薄的对象。 如果将平展轴设置为“自动平展”,则脚本会自动选取最小范围的轴作为平展轴。
平滑处理
平滑处理部分可以为控制的缩放和旋转配置平滑处理行为。
视觉对象
可以通过修改一个相应的视觉对象配置来配置边界控制的外观。 视觉对象配置是链接的或内联的可编写脚本对象,详情请见“配置对象”部分。
配置对象
控制附带一组配置对象,可存储为可编写脚本对象,并在不同的实例或预制件之间共享。 这些配置可以作为单独的可编写脚本的资产文件或预制件内嵌套的可编写脚本的资产进行共享和链接。 还可以直接在实例上定义其他配置,而无需链接到外部或嵌套的可编写脚本的资产。
边界控制检查器将通过在属性检查器中显示一条消息,来指示是共享某个配置还是将其内联为当前实例的一部分。 此外,共享实例无法直接在边界控制属性窗口中进行编辑,而是需要直接修改其链接到的资产,以避免共享配置发生任何意外更改。
目前边界控制为以下功能提供配置对象选项:
框配置
框配置负责呈现一个实心框,它的边界是通过碰撞器大小和框填充定义的。 可以设置下列属性:
- 框材料:定义在未发生交互时应用于呈现框的材料。 只有在设置了此材料的情况下,才会呈现一个框。
- 抓取框材料:用户通过近距离或远距离交互抓取与控制交互时框的材料。
- 平展轴显示比例:其中一个轴为平展轴时应用于框显示的比例。
缩放手柄配置
此属性抽屉可以修改边界控制缩放手柄的行为和可视化效果。
- 手柄材料:应用于手柄的材料。
- 抓取手柄材料:应用于已抓取手柄的材料。
- 手柄预制件:缩放手柄的可选预制件。 如果没有设置,MRTK 将默认使用立方体。
- 手柄大小:缩放手柄的大小。
- 碰撞器填充:要添加到手柄碰撞器的填充。
- 操作时绘制绳索:处于活动状态时,将绘制一条从交互的起始点到当前手或指针的位置的绳索线。
- 手柄忽略碰撞器:如果碰撞器在此处链接,手柄将忽略与此碰撞器的任何碰撞。
- 手柄场记板预制件:在控制平展时用于手柄的预制件。
- 显示缩放手柄:控制手柄的可见性。
- 缩放行为:可以设置为均匀或非均匀缩放。
旋转手柄配置
此配置定义旋转手柄行为。
- 手柄材料:应用于手柄的材料。
- 抓取手柄材料:应用于已抓取手柄的材料。
- 手柄预制件:手柄的可选预制件。 如果没有设置,MRTK 将默认使用球体。
- 手柄大小:手柄的大小。
- 碰撞器填充:要添加到手柄碰撞器的填充。
- 操作时绘制绳索:处于活动状态时,将绘制一条从交互的起始点到当前手或指针的位置的绳索线。
- 手柄忽略碰撞器:如果碰撞器在此处链接,手柄将忽略与此碰撞器的任何碰撞。
- 手柄预制件碰撞器类型:将与创建的手柄一起使用的碰撞器类型。
- 显示 X 轴的手柄:控制 X 轴手柄的可见性。
- 显示 Y 轴的手柄:控制 Y 轴手柄的可见性。
- 显示 Z 轴的手柄:控制 Z 轴手柄的可见性。
转换手柄配置
允许启用和配置用于边界控制的转换手柄。 请注意,默认情况下,转换手柄是禁用的。
- 手柄材料:应用于手柄的材料。
- 抓取手柄材料:应用于已抓取手柄的材料。
- 手柄预制件:手柄的可选预制件。 如果没有设置,MRTK 将默认使用球体。
- 手柄大小:手柄的大小。
- 碰撞器填充:要添加到手柄碰撞器的填充。
- 操作时绘制绳索:处于活动状态时,将绘制一条从交互的起始点到当前手或指针的位置的绳索线。
- 手柄忽略碰撞器:如果碰撞器在此处链接,手柄将忽略与此碰撞器的任何碰撞。
- 手柄预制件碰撞器类型:将与创建的手柄一起使用的碰撞器类型。
- 显示 X 轴的手柄:控制 X 轴手柄的可见性。
- 显示 Y 轴的手柄:控制 Y 轴手柄的可见性。
- 显示 Z 轴的手柄:控制 Z 轴手柄的可见性。
链接配置(线框)
链接配置启用了边界控制的线框功能。 可以配置以下属性:
- 线框材料:应用于线框网格的材料。
- 线框边缘半径:线框粗细。
- 线框形状:线框的形状可以是立方形或圆柱形。
- 显示线框:控制线框的可见性。
邻近感应配置
根据与手的距离,使用动画显示和隐藏手柄。 它含有两步缩放动画。 默认设置为 HoloLens 2 风格的行为。
- 接近效果激活:启用基于接近度的手柄激活
- 对象中等接近度:第一步缩放的距离
- 对象高接近度:第二步缩放的距离
- 远距离缩放:当手离开边界控制交互范围时,手柄资产的默认缩放值(上面由“手柄中等接近度”定义的距离。默认使用 0 来隐藏手柄)
- 中等距离缩放:当手位于边界控制交互范围时,手柄资产的缩放值(上面由“手柄高接近度”定义的距离。使用 1 来显示正常大小)
- “近距离缩放”:当手位于抓取交互范围时,手柄资产的缩放值(上面由“手柄高接近度”定义的距离。使用 1.x 来显示更大的尺寸)
- 远增长率:当手从中等距离移动到远距离时,接近缩放对象的缩放率。
- 中等增长率:当手从中等距离移动到近距离时,接近缩放对象的缩放率。
- 近增长率:当手从近距离移动到对象中心时,接近缩放对象的缩放率。
约束系统
使用边界控制手柄时,边界控制支持使用约束管理器来限制或修改转换、旋转或缩放行为。
属性检查器将在一个下拉列表中显示附加到同一游戏对象的所有可用约束管理器,以及一个用于滚动和突出显示所选约束管理器的选项。
事件
边界控制提供以下事件。 此示例使用这些事件来播放音频反馈。
- “旋转开始”:旋转开始时激发。
- 旋转停止:旋转停止时触发。
- 缩放开始:缩放开始时触发。
- 缩放停止:缩放停止时触发。
- 转换开始:转换开始时触发。
- 转换停止:转换停止时触发。
弹性(试验)
在通过边界控制操作对象时,可以使用弹性。 请注意,弹性系统仍处于试验状态。 若要启用弹力,请链接现有的弹力管理器组件,或通过 Add Elastics Manager
按钮创建并链接新的弹力管理器。
手柄样式
默认情况下,如果只分配 BoundsControl.cs
脚本,手柄将以 HoloLens 第一代样式显示。 若要使用 HoloLens 2 样式手柄,需要分配正确的手柄预制件和材料。
下面是 HoloLens 2 样式边界控制手柄的预制件、材料和缩放值。 可以在 BoundsControlExamples
场景中找到此示例。
手柄(HoloLens 2 样式设置)
- “手柄材料”:BoundingBoxHandleWhite.mat
- “抓取手柄材料”:BoundingBoxHandleBlueGrabbed.mat
- “缩放手柄预制件”:MRTK_BoundingBox_ScaleHandle.prefab
- “缩放手柄场记板预制件”:MRTK_BoundingBox_ScaleHandle_Slate.prefab
- “缩放手柄大小”:0.016(1.6 厘米)
- “缩放手柄碰撞器填充”:0.016(使可抓取的碰撞器在视觉上略大于手柄)
- “旋转手柄预制件”:MRTK_BoundingBox_RotateHandle.prefab
- “旋转手柄大小”:0.016
- 旋转手柄碰撞器填充:0.016(使可抓取的碰撞器在视觉上略大于手柄)
使用对象操控器的转换更改
边界控制可以与 ObjectManipulator.cs
结合使用,以实现在不使用手柄的情况下进行某些类型的操作(例如移动对象)。 操作手柄同时支持单手和双手交互。 可以使用手部追踪与靠近的对象进行交互。
为了使边界控制边缘在用户使用 ObjectManipulator
的远距离交互移动它时行为一致,建议将它的操作开始时 / 操作结束时的事件分别连接到 BoundsControl.HighlightWires
/ BoundsControl.UnhighlightWires
,如上面的屏幕截图所示。
如何使用 Unity 检查器添加和配置边界控制
- 向对象添加框碰撞器
- 将
BoundsControl
脚本分配给某个对象 - 配置选项,例如“激活”方法(请参阅下面的检查器属性部分)
- (可选)为 HoloLens 2 样式边界控制分配预制件和材料(请参阅下面的手柄样式部分)
注意
使用检查器中的“目标对象”和“边界覆盖”字段,在具有多个子组件的对象中分配特定对象和碰撞器。
如何在代码中添加和配置边界控制
立方体 GameObject 例化
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
使用 AddComponent<>() 将
BoundsControl
脚本分配给具有碰撞体的对象private BoundsControl boundsControl; boundsControl = cube.AddComponent<BoundsControl>();
直接在控制上或通过一个可编写脚本的配置来配置选项(参阅下面的检查器属性和配置部分)
// Change activation method boundsControl.BoundsControlActivation = BoundsControlActivationType.ActivateByProximityAndPointer; // Make the scale handles large boundsControl.ScaleHandlesConfig.HandleSize = 0.1f; // Hide rotation handles for x axis boundsControl.RotationHandlesConfig.ShowRotationHandleForX = false;
(可选)为 HoloLens 2 样式边界控制分配预制件和材料。 这仍然需要通过检查器进行分配,因为要动态加载材料和 prefab。
注意
不建议使用 Unity 的“资源”文件夹或 Shader.Find 来动态加载着色器,因为在运行时可能会丢失着色器置换。
BoxDisplayConfiguration boxConfiguration = boundsControl.BoxDisplayConfig;
boxConfiguration.BoxMaterial = [Assign BoundingBox.mat]
boxConfiguration.BoxGrabbedMaterial = [Assign BoundingBoxGrabbed.mat]
ScaleHandlesConfiguration scaleHandleConfiguration = boundsControl.ScaleHandlesConfig;
scaleHandleConfiguration.HandleMaterial = [Assign BoundingBoxHandleWhite.mat]
scaleHandleConfiguration.HandleGrabbedMaterial = [Assign BoundingBoxHandleBlueGrabbed.mat]
scaleHandleConfiguration.HandlePrefab = [Assign MRTK_BoundingBox_ScaleHandle.prefab]
scaleHandleConfiguration.HandleSlatePrefab = [Assign MRTK_BoundingBox_ScaleHandle_Slate.prefab]
scaleHandleConfiguration.HandleSize = 0.016f;
scaleHandleConfiguration.ColliderPadding = 0.016f;
RotationHandlesConfiguration rotationHandleConfiguration = boundsControl.RotationHandlesConfig;
rotationHandleConfiguration.HandleMaterial = [Assign BoundingBoxHandleWhite.mat]
rotationHandleConfiguration.HandleGrabbedMaterial = [Assign BoundingBoxHandleBlueGrabbed.mat]
rotationHandleConfiguration.HandlePrefab = [Assign MRTK_BoundingBox_RotateHandle.prefab]
rotationHandleConfiguration.HandleSize = 0.016f;
rotationHandleConfiguration.ColliderPadding = 0.016f;
示例:使用 MinMaxScaleConstraint 设置最小、最大边界控制比例
若要设置最小和最大比例,请将 MinMaxScaleConstraint
附加到控制。 当边界控制自动附加和激活约束管理器时,MinMaxScaleConstraint 将在附加和配置后自动应用于转换更改。
还可以使用 MinMaxScaleConstraint 设置 ObjectManipulator
的最小和最大比例。
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
bcontrol = cube.AddComponent<BoundsControl>();
// Important: BoundsControl creates a constraint manager on start if one does not exist.
// There's no need to manually attach a constraint manager.
MinMaxScaleConstraint scaleConstraint = bcontrol.gameObject.AddComponent<MinMaxScaleConstraint>();
scaleConstraint.ScaleMinimum = 1f;
scaleConstraint.ScaleMaximum = 2f;
示例:围绕游戏对象添加边界控制
若要在对象周围添加边界控制,只需向该对象添加 BoundsControl
组件:
private void PutABoundsControlAroundIt(GameObject target)
{
target.AddComponent<BoundsControl>();
}
从边界框迁移
使用边界框的现有预制件和实例可以通过 MRTK 工具包中的迁移窗口升级到新边界控制。
如果要升级单个边界框实例,还可以使用组件的属性检查器中的迁移选项。