在 Unity 的地理空間建立者中,透過程式輔助方式建立及編輯錨定標記

本指南說明如何使用 Geospatial Creator 編寫 C# 指令碼,快速完成常見工作,例如在 Unity 的編輯模式中建立及移動 ARGeospatialCreatorAnchor 物件。這項功能可讓您從預先定義的清單 (例如試算表或 KML 檔案) 建立多個錨點。

Unity 中的 Geospatial Creator 可讓您在 Unity 編輯器中預覽地理空間內容。我們的快速入門指南介紹了地理空間創作者,並逐步引導您使用 Unity 編輯器 UI,以最少的程式設計建構第一個支援地理空間的擴增實境體驗。對於較進階的專案,您可能會想以程式輔助方式建立及操作 Geospatial Creator 遊戲物件,而非使用 Unity 編輯器 UI。

本指南假設您已熟悉快速入門中介紹的基本地理空間創作者概念,並準備開始在場景中加入地理空間創作者錨點。您必須啟用 Geospatial Creator,並使用 API 金鑰和場景中的初始 AR 工作階段物件進行設定。如果是從頭開始,請先按照快速入門指南操作,包括「啟用地理空間內容創作者」部分,再繼續操作。

開始使用

在這個範例中,假設您在美國加州舊金山的市政廳周圍,有一系列已知的位置,且您想在這些位置放置 AR 內容。您需要在這些位置建立錨點物件,然後將基本幾何圖形附加到這些錨點。

您必須先指定 ARGeospatialCreatorOrigin,才能建立錨點。ARGeospatialCreatorOrigin 是用於將緯度、經度和高度轉換為 Unity 世界座標,或從 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 擴充功能隨附的地理空間範例應用程式開始,錨點管理工具會附加至「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 應用程式中,在地面層級的每個位置放置一個 1 公尺立方體。以下程式碼會建立 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 屬性,在編輯器的場景檢視畫面中微調屋頂錨點的高度。在本例中,屋頂的 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 指定,因此不需要使用僅限編輯器的高度覆寫值。當然,如果編輯器中地圖圖塊幾何圖形的高度與實際世界相比不正確,您還是可以使用編輯器覆寫功能,在場景檢視畫面中重新調整錨點位置。

半球體上的地理空間錨點