地形海拔

借助地形高度,您可以向使用 Maps SDK for Unity 制作的游戏添加样式可完全定制的三维地形。利用 Google 地球的海拔数据,您可以为游戏内地形添加写实性维度。您可以展示在现实世界中的特定位置会发现的山丘、山谷和其他陆地地图项,让玩家可以更轻松地识别周围的环境和自己的方位。

例如,下图显示了科罗拉多大峡谷的地形高度渲染。图像使用相对简单的样式,在斜坡上混合岩石和草地纹理,但也可以采用更复杂的样式。

科罗拉多大峡谷的地形海拔图片

由于地形高度是与 Unity Terrain Engine 集成的,因此会生成 Unity 地形图块。系统会自动调整现有的地图项,使其与地形对齐。您可以使用地形图层完全控制地形的样式,并定义根据地形属性混合图层的自定义方法。这与 Unity 的地形绘制工具类似,但可以在运行时应用。您不需要了解地形网格的详细信息。

创建每个地形图块后,Maps SDK for Unity 事件系统都会通知游戏。如果需要,您可以将其他逻辑集成到地形生成流水线中。

Maps SDK for Unity 包含一个示例场景,其中演示了如何使用地形图层设置地形高度的样式。您可以在 Unity 的 Project 窗格的 Assets > GoogleMaps > samples 文件夹内找到此场景。该场景包含一个名为 Terrain Example Script 的 GameObject,其中包含 C# 脚本组件 TerrainExample.cs

如需详细了解示例场景,请参阅 Maps SDK for Unity 示例场景

启用地形高度

在调用 Awake() 之前,请使用 Maps SDK for Unity Maps Service 组件启用地形海拔。

要使用地图服务组件启用地形海拔,请执行以下操作:

  1. 在 Unity Inspector 中,打开 Maps Service 脚本组件。

  2. 地图项选项 > 地形下,选中启用地形复选框。

配置地形参数

初始化地形高度时,您必须在 MapsService 组件中配置以下参数。

TerrainMeshMetersPerPoint

生成的 Unity 地形图块的目标分辨率(以米/点为单位)。默认值为 1。

每个地形图块的实际分辨率可能与指定的 TerrainMeshMetersPerPoint 值不同。Unity 地形图块的高度图分辨率必须为 2 加上 1。Maps SDK for Unity 会将提供的值四舍五入为最接近的 2 再加上 1 的幂,以满足此要求。

与混合缩放组件搭配使用时,每当缩放级别降低时,TerrainMeshMetersPerPoint 值都会自动加倍。

AltitudePrecision

地形海拔高度的垂直精确度,介于 0.01(厘米级精确度)和 10000(10 公里级精确度)之间。默认值为 0.01。

为地形表面着色

Unity 的地形引擎会根据一系列 alpha 图,将一组地形图层混合在一起渲染地形表面。每个地形图层均有一些关联的纹理(例如漫射、法线)。一个地形图层可由多个地形图块共享。

每个地形图块的每个地形图层都有一个 Alpha 地图,用于控制该图层在图块表面上任意给定点的混合权重。所有层在任意给定点的权重总和应等于 1。地形图层纹理在地形表面上平铺,而 Alpha 地图会进行缩放,使其覆盖每个图块的整个表面。

出于性能方面的考虑,必须以编程方式生成 Alpha 地图。运行着色器程序,从包含以颜色标识的地图项的特征遮罩图片中进行采样。系统会根据每个材质的常规样式配置中提供的材质为功能蒙版着色,该材质包含在 AlphaMapsNeedPaint 事件的参数中。使用适当的非照亮材料,具有统一的颜色来为每个地图项着色。对于区域或线段等基本地图地图项,请确保您的材质使用合适的与基本地图兼容的着色器

默认情况下,系统不会将任何地图项渲染到地图项掩码中。如需将地图项渲染到地图项蒙版中,请将其样式配置中的 GameObjectLayer 字段设为您在 TerrainStyle 对象中为地形渲染指定的同一图层。如果要使用地平面对象来覆盖地图项之间的地面间隙,您还必须将此平面放置在地形渲染层上,并分配适当的材质来避免地图项蒙版中的间隙。

地图项蒙版的绘制方法是使用正交投影在场景的相关区域内渲染地形绘制层。如果您没有使用适当的颜色编码的游戏对象覆盖整个区域,则底层 Skybox 将显示在功能蒙版中。Maps SDK for Unity 将确保在尝试绘制地图项遮罩之前创建所有相关的地图项游戏对象,但如何放置地平面则由您自行负责。Maps SDK for Unity 提供的示例中已经放置了一个合适的地平面对象。

Alpha 版地图绘制本身是在您为 AlphaMapsNeedPaint 事件指定的处理程序内指定的协程中进行的。此协程的内容因您期望的 Surface 外观和方法而异,但在返回协程之前的某个时间点,必须设置地形图块的 Alpha 映射。这些纹理以四个一组的形式打包到 ARGB 控制纹理中,每个通道都表示给定图层的 Alpha 映射。用于写入这些控件纹理的技术因您使用的 Unity 版本而异。例如,在 Unity 2019.2 及更高版本中,请使用 TerrainData.CopyActiveRenderTextureToTexture。随 Maps SDK for Unity 分发的地形示例展示了适用于受支持 Unity 版本的推荐技术。

请注意,绘制协程可能会被取消而不返回,因此您必须使用 AlphaMapsNeedPaintArgs 提供的委托来注册终结器,以清理您为在该协程内使用的所有临时资源(例如,临时渲染纹理)。

如需了解详情,请参阅打包示例。

置换结构

启用地形高度后,建筑物和地标等结构会与地形垂直对齐。

对于凸形结构,每个结构都放置在与其底部相交的最低高度,以确保地形和结构底部之间没有间隙。然后拉伸每个伸出部分,以防止任何屋顶夹入地面,同时仍然保持建筑物其余部分的整体面貌。

建模结构仅遵循上述放置流程,而不对结构模型进行任何修改。由于建模结构是任意形状,因此足迹由结构中最低点的顶点定义。

与 Unity 交互

使用父级和转换

默认情况下,Maps SDK for Unity 生成的 GameObject 都是包含 MapsService 组件(地图锚点)的 GameObject 的转换的父级。所有非地形 GameObject 都会正确遵循地图锚点的转换。

Unity 不支持地形对象的旋转和缩放转换。因此,应用这些类型的转换时,Maps SDK for Unity 生成的 Terrain GameObject 无法旋转或缩放,也无法遵循父级 GameObject。支持平移,前提是 Terrain GameObject 未标记为 static

因此,Maps SDK for Unity 不支持任何涉及地形的对象转换,尝试进行此类转换可能会导致异常行为或意外行为。

设备端渲染

Unity 的地形系统使用特定资源进行设备端渲染。在修改时,向场景添加地形时会自动包含这些区域。如果仅在运行时使用(如在 Maps SDK for Unity 中),则必须明确包含这些资源。否则,地形可能会无法正确渲染或根本无法渲染。

Unity 的推荐方法是按照以下步骤添加这些资源:

  1. 在场景中的某个位置添加地形 GameObject。

  2. 通过在检查器中通过该组件的设置,为 GameObject 的地形组件启用 Draw Instanced

这样可以自动向所有必要的资源添加依赖项,并且可应对 Unity 版本之间的变化。然后,您可以在检查器中取消选中此 Terrain GameObject 名称旁边的复选框,将其隐藏。此方法在捆绑的地形示例场景中演示:

包含地形素材资源,如地形示例场景所示。