在 Unity 中的 Geospatial Creator 中以编程方式创建和修改锚点

本指南介绍如何使用 Geospatial Creator 编写 C# 脚本 快速完成常见任务,例如创建和移动 ARGeospatialCreatorAnchor 对象。对于 根据预定义的列表(如电子表格或 KML)创建多个锚点 文件。

借助 Unity 中的 Geospatial Creator,您可以预览 Unity 编辑器。我们的快速入门指南介绍了 Geospatial Creator,并详细介绍了如何使用 Unity 编辑器界面,通过最少的编程工作构建您的首个支持地理空间的 AR 体验。对于更高级的项目,您可能需要以编程方式创建和操控 Geospatial Creator GameObject,而不是使用 Unity 编辑器界面。

本指南假定您熟悉“快速入门”中介绍的基本 Geospatial Creator 概念,并且可以开始向场景添加 Geospatial Creator 锚点。您需要启用 Geospatial Creator,并使用 API 密钥对其进行配置,还需要在场景中添加初始 AR 会话对象。如果是从头开始,请按照快速入门指南操作,并逐步 包括“启用地理空间 创作者” 部分,然后再继续。

使用入门

在本示例中,假设您的市政厅周围有一组已知的位置 美国加利福尼亚州旧金山,您要放置 AR 内容的位置。您需要在这些位置创建锚点对象,然后将基本几何图形附加到这些锚点。

在创建锚点之前,您应该先指定一个 ARGeospatialCreatorOrigin,这是转换的参考点 与 Unity 世界坐标之间的纬度、经度和海拔高度。 该原点还将包含一个 CesiumGeoreference 子组件和一个 Cesium3DTileset 子对象,这让 Cesium 能够在 Unity 编辑器的场景视图中渲染周围区域。为此,您需要一个 Google 地图图块 API 密钥,如快速入门中所述

创建来源

API for Geospatial Creator 包含用于创建 ARGeospatialCreatorOrigin,并添加所需的 Cesium 组件。 以下代码会使用给定的 Map Tiles API 密钥,在地图上附近的某个经纬度和海拔位置创建起点:

ARGeospatialCreatorOrigin origin =
  GeospatialCreatorCesiumAdapter.CreateOriginWithCesiumGeoreference(
    37.77954, -122.417581, 0.0, "<MAP_TILES_KEY>");

默认情况下,此对象位于 Unity 世界坐标系中的 (0, 0, 0),这对于本例来说非常适用。

获取 ARAnchorManager 引用

ARAnchorManager 需要在运行时解析地理空间锚点,因此您 还需要引用场景中的 ARAnchorManager。如果您从 与 ARCore Extensions(锚点)ARCore 扩展程序捆绑的 Geospatial 示例应用 管理器已连接到“AR 会话来源”GameObject。假设您的场景中只有一个锚点管理器,您可以通过以下方式获取对它的引用:

ARAnchorManager anchorManager =
    Resources.FindObjectsOfTypeAll<ARAnchorManager>()[0];

现在,您已经有了源和锚点管理器,可以开始创建 ARGeospatialCreatorAnchor 对象了。

创建地形锚点

请考虑以下包含 double 值的二维数组,它表示 位于 美国加利福尼亚州旧金山市政厅:

double[,] _cityHallEastPoints = {
    { 37.77936, -122.418617 }, // in front of city hall
    { 37.77965, -122.418680 }, // right of city hall
    { 37.77917, -122.418577 }}; // left of city hall

假设您想在地面的每个位置分别放置一个一米立方体 在 AR 应用中实现这一点。以下代码会创建 ARGeospatialCreatorAnchor 对象,并将其属性分配给适当的值:

for (int i = 0; i < _cityHallEastPoints.GetLength(0); i++)
{
  ARGeospatialCreatorAnchor anchor =
    new GameObject("City Hall " + i).AddComponent<ARGeospatialCreatorAnchor>();
  anchor.Origin = origin;
  anchor.AnchorManager = anchorManager;
  anchor.Latitude = _cityHallEastPoints[i, 0];
  anchor.Longitude = _cityHallEastPoints[i, 1];
  anchor.AltitudeType = AnchorAltitudeType.Terrain;

  GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
  cube.transform.parent = anchor.transform;
}

这样便可在每个点创建地形锚点。Geospatial Creator 会通过计算相对于 ARGeospatialCreatorOrigin 对象的位置,自动将锚点放置在适当的 Unity 世界坐标处。要调整 地形锚点的海拔高度,请设置以米以上为单位的 Altitude 属性,或者 隐藏在地面之下

在运行时,地形锚点将在地面上为正在运行的应用解析, Altitude 属性的偏移量。但在编辑器的场景视图中 默认在 WGS84 海拔 0 处渲染,而不是相对于 3D 图块 几何图形。您通常不希望在此处看到它们,因此您可以覆盖 通过设置 将 UseEditorAltitudeOverride 属性设置为 true,并将海拔高度指定为 使用 EditorAltitudeOverride 属性实现 WGS84 米:

anchor.UseEditorAltitudeOverride = true;
anchor.EditorAltitudeOverride = -13.5; // WGS84 altitude at ground level for City Hall plaza

这两个属性在编辑器模式下不会产生任何影响, 编译到正在运行的应用中

市政厅广场中的地理空间锚点

创建屋顶锚点

对于下一个锚点,假设您想在市政厅的屋顶上放置一个锚点。可以完全按照相同的方式创建锚点,只不过 AltitudeType 属性会设置为 AnchorAltitudeType.Rooftop

ARGeospatialCreatorAnchor cityHallRoofAnchor =
  new GameObject("City Hall Roof").AddComponent<ARGeospatialCreatorAnchor>();
cityHallRoofAnchor.Origin = origin;
cityHallRoofAnchor.AnchorManager = anchorManager;
cityHallRoofAnchor.Latitude = 37.77959;
cityHallRoofAnchor.Longitude = -122.419006;
cityHallRoofAnchor.AltitudeType = AnchorAltitudeType.Rooftop;

GameObject roofCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
roofCube.transform.parent = cityHallRoofAnchor.transform;

与地形锚点类似,您可以微调屋顶的高度 使用 UseEditorAltitudeOverrideEditorAltitudeOverride 属性。在此示例中, 屋顶大约有 10.7 米

屋顶上的地理空间锚点

在特定海拔高度创建锚点

我们的最后一点锚将放置在市政厅圆顶的顶部。对于此锚点,精确的海拔高度非常重要,因此您将使用 WGS84 锚点(而非地形或屋顶锚点)来明确设置海拔高度:

ARGeospatialCreatorAnchor cityHallDomeAnchor =
  new GameObject("City Hall Dome").AddComponent<ARGeospatialCreatorAnchor>();
cityHallDomeAnchor.Origin = origin;
cityHallDomeAnchor.AnchorManager = anchorManager;
cityHallDomeAnchor.Latitude = 37.77928;
cityHallDomeAnchor.Longitude = -122.419241;
cityHallDomeAnchor.AltitudeType = AnchorAltitudeType.WGS84;
cityHallDomeAnchor.Altitude = 73;

GameObject domeCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
domeCube.transform.parent = cityHallDomeAnchor.transform;

无需使用编辑器专用的海拔高度替换值,因为海拔高度是 已根据 WGS84 指定。当然,如果地图图块的高度 与现实世界相比,编辑器中的几何图形不正确, 您仍然可以使用编辑器替换项在场景中重新定位锚点 视图。

圆顶上的地理空间锚点