代理力
代理力可用于表达出像弹簧一样灵活的力,能够将代理拉到最终位置。这些力通常是相对于其他对象和周围表面对齐的合力。 您可以使用这些力来建模常见的放置场景,例如计算如何在对象之间创建空间,或者如何朝着用户和在用户面前拉动对象。
上面的截屏显示了施加多个力的水壶。水壶会占用空间,位于一个表面上,应该靠近垂直墙壁和水平边缘,并且在壶嘴的正上方和前方有间隙(不应有任何东西)。 杯子会占用空间,应该位于表面上,并且与水壶对齐。
下一节介绍关于在应用程序中使用代理力的概念和工作流程。内容包括基本力的创建、配置和排列处理步骤,还包括一个可用于快速入门的真实示例。 阅读此内容后,您应该会学习到必要的知识,可以将代理力整合到 Unity MARS 应用程序中。
力组件
代理力系统使用的关键概念、类型和主要属性如下:
力 (ProxyForces
)
收集下面的力并将它们施加到此对象上。每个游戏对象对应一个。如果启用了 Require Forces* 选项,请设置力作为起始条件以筛选掉无效的起始状态。
对齐 (ProxyAlignmentForce
)
施加使该对象相对于另一个对象对齐的力。这支持多个目标关系。根据应用程序的目的,这些目标关系的工作方式如下:
目标关系 | 描述 |
---|---|
Move To And Align With | 移动并旋转以与目标对象对齐。 |
Move To And Face | 移动到目标对象并面对它(面向 Z 轴)。 |
Center In Front Of And Face | 在对象前面移动并面对它(面向 Z 轴),不考虑距离。 |
Scene Initial Relative Pose | 保存从目标到该对象的初始对齐(在场景中),并施力以重新获得该对齐。 |
Scene Initial Relative Angle | 保存从目标到该对象的初始角度(在场景中),并施力以重新获得该角度。 |
Scale forces 用于控制朝目标姿态施加的力量。将该值设置为 0 可使力无效,而设置为 1 表示施加全力。
区域 - 占用 (ProxyRegionForceOccupancy
)
描述对象如何占用空间并施力以防止该对象与其他占用的空间发生碰撞。默认情况下,Unity MARS 将一个单位立方体分配给区域变换组件,并将此立方体创建为代理的子项。此变换组件定义了区域的形状和姿态。
注意:由于代理力不依赖于 Unity 的物理系统,因此,如果您想更改任何代理力的区域变换组件,只需更改在 Region Transform 对象字段中分配的变换组件的缩放即可。
间隙区域用于为对象周围的空白/负空间建模。这些区域可能与其他间隙重叠,但会与占用的区域发生碰撞。如果启用 Is Padding 选项,则代理将避开占用的区域,但会允许与其他间隙区域重叠。
区域 - 朝向 (ProxyRegionForceTowards
)
描述被其他对象(一个附着形状或捕捉点)吸引的区域。“朝向”区域通常用于描述应与诸如墙壁和/或地板之类的表面接触的对象部分。
可使用以下参数来配置这种力:
参数 | 描述 |
---|---|
Towards Layers | 将吸引力仅过滤到选定的图层。 |
Towards Alignment | 将吸引力过滤到设置的对齐方式(垂直、水平向上等)。 |
Towards Edge Only | 吸引力只能朝向对象的边缘。例如,在定义角对齐时可以使用此参数。 |
Region Transform | 描述相对于代理的附着或吸引区域的形状。 |
区域 - Plane2D (ProxyRegionForcePlane2D
)
描述在对象原点处被吸引到其他平面的平坦 2D 区域,并提供了一种方法根据代理上的其他条件自动提取此区域的大小和对齐方式。
可使用以下参数来配置这种力:
参数 | 描述 |
---|---|
Use Plane Size Condition | 启用后,从开始时可用的平面大小条件获取区域大小。 |
Use Alignment Condition | 启用后,从开始时可用的对齐条件获取区域的对齐方式。 |
Plane Size | 2D 平面在 X 和 Y/Z 轴上的大小(可自动从关联的平面大小条件中提取)。 |
Plane Alignment | 定义要与哪些平面对齐,例如仅水平向上(可自动从关联的对齐条件中提取)。 |
示例
下面介绍了两个示例:
- 一个使 Avatar 从表面看向您的简单工作流程
- 一个更大的“二人晚餐”示例介绍
入门:制作一个从表面看向您的 Avatar
代理力是添加到代理的 Unity MARS 组件。根据您拥有的组件的组合,可以实现不同的效果。代理力对于具体的对齐很有用,例如对象之间保持间距以及相对于附近边缘、墙壁和其他对象对齐。代理力通常与平面条件一起使用以完善平面内的放置。
本节向您展示如何制作一个附加到代理的简单模型来看向并跟随摄像机。
设置代理(在添加力之前)
在使用代理力之前,需要在 Avatar 的目标位置设置一个代理。为此,请创建一个水平平面代理。可从以下任一位置执行此操作:
- MARS Panel(单击 Horizontal Plane 按钮)。
- Hierarchy 视图(右键单击,然后从上下文菜单中 MARS > Presets > Horizontal Plane)。
接下来,向 Horizontal Plane 代理添加一个模型作为该代理的子项。由于启用了 Show Children on Tracking Action 选项,此模型仅在有匹配项时才可见。
向代理添加力
现在已经建立了模型,接下来可以向模型添加力了。为了使模型 Avatar 面对摄像机,需要两个力:
- 使 Avatar 朝向摄像机的力
- 将 Avatar 限制在代理所附加到的平面的力
要执行此操作,请遵循以下步骤:
- 选择水平平面代理。
- 在 Forces 选项卡中,单击 Add force 按钮,然后单击 Align to Camera 按钮。
- 再次单击 Add force,然后单击 Snap to Plane 2D 按钮。
代理现在有三个组件:
ProxyForces
,在这里可以配置常规的力设置,例如移动ProxyAlignmentForce
,在这里可以将代理对齐到摄像机ProxyRegionForcePlane2D
,在这里可以将 Avatar 限制到平面
测试创建的力
要测试所做的设置,请单击 Play 按钮,并开始扫描是否有任何已加载的环境。Avatar 应放置在第一个扫描到的平面上,并看向摄像机。
结论
如果执行了上述步骤,现在应该有一个可以在任何扫描的平面上显示的简单代理。该代理包含一个 Avatar,这个 Avatar 面向摄像机,但由于受到力的影响而被限制到平面。
本教程使用 Align to Camera 和 Snap to Plane 2D 力,但也可以尝试使用其他力。例如:
- Occupied Region,这种力可以防止对象与其他对象重叠
- Snap to Vertical Surfaces,这种力定义了对象上吸引到水平平面(对象上)的区域
- Align to Other Proxy,这种力可以将对象与其他对象对齐(例如,一个控制面板,这个面板尝试将其自身放置在基本项附近)。
如前文所述,Unity MARS 中的力是可添加到代理的组件。根据这些力的组合方式,可以实现不同的效果。要了解每个组件对代理的影响,请参阅本页上的力组件部分,其中提供了每种力的详细说明。
示例:使用力的“二人晚餐”
本教程将引导您完成设置来用力放置所有对象,从而在 AR 二人晚餐中放置所有餐具、锅和酒。
上方的缩略图链接到“二人晚餐”示例的视频;该示例使用了 Unity MARS 中的代理力。
设置基本场景环境
首先创建晚餐的基本餐桌设置。为您和您的伴侣添加碟子网格以及周围的餐具。
设置所有网格之后,将这些网格转换为代理平面。为此,请右键单击每个游戏对象,然后从上下文菜单中选择 MARS > Turn Into > Proxy Plane。
最后,将平面条件附加到您要为晚餐放置的所有游戏对象上的代理。确保平面大小条件禁用了最大大小,并且设置了最小大小以覆盖对象的底部。
为了能够自由移动摄像机,请按照下列步骤操作:
- 创建 Reference Person 游戏对象。
- 将这个对象转换为代理平面。
- 添加 Align to camera 力。
- 确保 Allowed motion 设置为 Move And Rotate Y,且 Target Relation 设置为 Move To And Align With。
组织碗碟
对所有碟子进行基本设置后,向第一个碟子添加 Align to other proxy 和 Snap to Horizontal Surfaces 力。
将第一个碟子上的 Target Proxy 设置为先前创建的 Proxy Reference Person。两个代理之间将出现一条绿线。
对第二个碟子重复以上步骤,但将 Target Proxy 设置为第一个碟子。另外,请确保 Target Relation 设置为 Scene Initial Relative Pose。
配置所有餐具的设置
对于所有餐具,请确保所有代理均具有以下条件和力:
Proxy Exclusivity 设置为 Shared,使所有代理都可以放置在同一个检测到的平面中。
Align to other Proxy 设置为 Proxy Reference Person,使每个游戏对象处于相对于用户的正确位置。
添加一个 Alignment Condition(如果尚不存在)并确保此设置为 Horizontal Up。另外,添加一个 Snap to Plane 2D 力。
最后,向所有代理添加一个 Occupied Region 力 (1),使这些代理不会彼此重叠。为此,请单击 Occupied Region 力。此时将创建一个 Region Occupied 游戏对象 (2)。要设置占用的体积,请修改 Region Occupied 游戏对象的 Scale 设置。
单击 Play 按钮,然后在加载的环境中查找空餐桌。您应该会看到对象被放置在您的面前。
结论
本教程介绍了在用户直接观看的表面上放置多个游戏对象的步骤。这些游戏对象使用力让自身适应这个表面。我们已经看到,可以使用力在给定的空间中布置多个对象彼此的相对位置。
作为练习,您可以对所有代理力禁用 Continuous Solve,以使对象在首次放置后保持原来的位置。
此示例的故障排除
如果一次仅出现一个对象,请尝试将所有相关代理的 Exclusivity 设置为 Shared(也就是说,它们全部“共享”同一个表面)。
为避免对象重叠,请对上方的每个对象施加 Region Occupancy 力并进行调整。
要在碟子和餐具之间留一点空间,您可以添加 Region Padding 力并根据需要调整空白空间大小。
作为参考,以下截屏显示了所有主要力类型的通用配置:
在没有代理的情况下使用力
可在没有代理的情况下在 Unity MARS 中使用力。仅建议高级用户这样做。
要在没有代理的情况下使用力,请将 ProxyForces 组件及其关联的力添加到空游戏对象而不是代理。这些力从一开始就会启用。
相反,一个代理上的力仅在关联的代理找到匹配项后才会运行,并且仅在匹配项激活时才会施加这些力。此外,这些力还将在代理到达 SetPose 和其他动作之前更新代理的姿态。
关于代理力的重要注意事项
由于代理力不依赖于 Unity 的物理系统,因此,任何代理力的区域变换组件都由变换组件确定,而缩放决定了相关变换组件的边界。如果要修改代理力的区域变换组件的边界,则必须修改链接的变换组件的缩放以设置相关体积。
故障排除/常见问题解答 (FAQ)
- 摄像机移动时会出现“抖动”动作。
- 解决方案:禁用 Set Pose Action 并将 Follow Match Updates 设置为 false。如果在扫描时对象似乎在跳来跳去,这可能是因为 Set Pose Action 在移动时将对象更新为所检测到的平面的“中心”。
- 我想在同一表面上放置两个或多个对象。
- 解决方案:将代理的 Exclusivity 设置为 Shared 而非 Exclusive。Shared 允许多个代理共享同一数据平面,但是您可能要使用 Occupancy Regions 来确保代理不重叠。默认设置为 Reserved,可确保任何特定的数据段一次只能由一个代理使用。Read Only 导致放置对象时不检查是否有其他代理正在保留或共享该数据。
- 我希望对象放置后不移动。
- 解决方案:禁用实时力解算(将 Proxy Forces / Continuous Solve 选项设置为 false)。
- 静态对象无法解算为正确的位置。
- 解决方案:解决此问题的最简单方法是通过编写脚本。可调用
ProxyForces.TrySingleSolve
,或者是启用和禁用ProxyForces.continuousSolve
。此外,通常建议用户进行交互以纠正姿态,可以在启用连续解算时使用这种方式。
- 解决方案:解决此问题的最简单方法是通过编写脚本。可调用