Version: 2017.3
空间映射基本低级 API 用法
空间映射 (Spatial Mapping) 组件

空间映射最佳实践

由于空间映射可能生成的数据量以及生成该数据对速度和性能的影响,因此在使用低级 API 时需要考虑许多问题。

如果没有仔细规划应用程序对空间映射的使用,应用程序的速度和性能可能会很差。以下是空间映射可能产生的一些潜在问题,以及有关如何解决这些问题的最佳实践建议。

问题:生成碰撞数据非常慢

生成碰撞数据时会在生成空间映射数据时使用大部分 CPU 算力。请求不会被使用的碰撞数据会不必要地占用 CPU 资源并缩短电池续航时间。

最佳实践解决方案:

  • 仅在必要时请求碰撞数据。避免在不需要时请求碰撞数据可降低其他空间映射请求的延迟,并延长电池续航时间。
  • 仅请求最重要的__表面__。使用__表面__的更新时间和包围盒来确定数据请求的优先级。

问题:较高的三角形密度会产生大量几何体

通过 RequestMeshAsync 请求__表面__数据时,可以在 SurfaceData 结构中指定 trianglesPerCubicMeter 的较大值。这样会产生非常大量的几何体,尤其是在具有大量对象的空间(例如杂乱的办公室)中。大量几何体会增加数据生成延迟和内存使用量。此外,较高的网格密度也会降低渲染和物理系统等运行时系统的运行速度。

最佳实践解决方案:

  • 请求所需的空间映射数据的最小分辨率。请求生成的网格的较低分辨率可以减少处理请求所需花费的 CPU 时间。这样可以降低功耗,延长电池续航时间,并降低网格数据交付延迟。较低分辨率网格也对运行时性能的负面影响较小,且在内存要求方面占用的资源较少。对于期望低复杂度几何体的物理系统运行时尤其如此。

问题:太多网格请求处于排队状态导致执行不必要的工作

调用 Update 方法时,SurfaceObservers 会报告所在体积中所有已添加、更新和移除的__表面__。

如果将所有已更改的__表面__作为一个列表添加到工作队列中,可能导致在系统删除这些表面后__表面__保留于工作队列中。删除后仍然位于工作队列中的__表面__在系统中移动时仍会占用 CPU 时间,但不生成任何网格数据。这会增加所有处于等待状态的请求的延迟时间。

最佳实践解决方案:

  • 尽可能限制工作队列中的__表面__数量。鉴于与网格工作队列相关的长延迟,一次只应使用一个 RequestMeshAsync。应用程序可以使用__表面__报告的更新时间和边界来确定 RequestMeshAsync 调用的优先级。
  • 确定__表面__数据请求的优先级,使应用程序首先获取最重要的数据。例如:
    • 新__表面__的优先级高于对现有表面的更新。
    • 更近__表面__的优先级高于更远表面。

问题:重叠或相邻的 SurfaceObservers 报告相同的网格,导致重复的 RequestMeshAsync 调用

每个 SurfaceObserver 会报告与其体积重叠的所有__表面__的更改。一个__表面__可以重叠多个靠近的 SurfaceObserver 体积,因此应用程序代码可能会多次请求相同的__表面__。

最佳实践解决方案:

  • 在所有 SurfaceObservers 之间使用单个工作提交队列。 通常,单个 SurfaceObserver 就足够了,因为只用一个可以避免应用程序的复杂性。 但是,__空间映射__有几个高级用例需要多个 SurfaceObservers。这些情况下,应在所有 SurfaceObservers 之间使用单个工作队列来唯一确定网格请求的优先级。
  • 如果应用程序不需要更高的复杂性,请使用单个 SurfaceObserver

问题:更新 SurfaceObserver 不会生成 onSurfaceChanged 回调

这个常见问题通常是由一个或多个设置问题引起。

最佳实践解决方案:

  • 确保通过 SetVolumeAsAxisAlignedBox 等函数在 SurfaceObserver 上设置有效体积。
  • 确保在 Player SettingsPublishing Settings 部分选中了 Spatial Perception
空间映射基本低级 API 用法
空间映射 (Spatial Mapping) 组件