本指南介绍了如何使用 Geospatial Creator 编写 C# 脚本,以便快速完成常见任务,例如在 Unity 的“Edit”模式下创建和移动 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 密钥,如快速入门中所述
创建来源
Geospatial Creator 的 API 包含一个工厂方法,用于在场景中创建 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 捆绑的地理空间示例应用开始,则锚点管理器会附加到“AR 会话起源”游戏对象。假设您的场景中只有一个锚点管理器,您可以通过以下方式获取对它的引用:
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;
与地形锚点类似,您可以使用 UseEditorAltitudeOverride
和 EditorAltitudeOverride
属性在编辑器的场景视图中微调屋顶锚点的海拔。在本示例中,屋顶的 WGS84 海拔大约为 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 指定,因此无需使用仅限编辑器的海拔替换项。当然,如果编辑器中地图图块几何图形的高度与现实世界相比不正确,您仍然可以使用编辑器替换项在场景视图中重新定位锚点。