Menggunakan anchor Geospasial untuk memosisikan konten dunia nyata di Unity

Anchor geospasial adalah jenis anchor yang memungkinkan Anda menempatkan konten 3D di dunia nyata.

Jenis anchor Geospasial

Ada tiga jenis anchor Geospasial, yang masing-masing menangani ketinggian secara berbeda:

  1. Anchor WGS84:
    Anchor WGS84 memungkinkan Anda menempatkan konten 3D pada lintang, bujur, dan ketinggian tertentu.

  2. Anchor medan:
    Anchor medan memungkinkan Anda menempatkan konten hanya menggunakan garis lintang dan bujur dengan ketinggian yang relatif terhadap medan di posisi tersebut. Ketinggian ditentukan secara relatif terhadap tanah atau lantai seperti yang diketahui oleh VPS.

  3. Anchor atap:
    Anchor atap memungkinkan Anda menempatkan konten hanya menggunakan garis lintang dan bujur dengan tinggi yang relatif terhadap atap bangunan di posisi tersebut. Ketinggian ditentukan relatif terhadap bagian atas bangunan seperti yang dikenal oleh Streetscape Geometry. Ini akan ditetapkan secara default ke ketinggian medan ketika tidak ditempatkan di bangunan.

WGS84 Medan Atap
Posisi Horizontal Lintang, Bujur Lintang, Bujur Lintang, Bujur
Posisi Vertikal Relatif terhadap ketinggian WGS84 Relatif terhadap tingkat medan yang ditentukan oleh Google Maps Relatif terhadap tingkat atap yang ditentukan oleh Google Maps
Perlu diselesaikan server? Tidak Ya Ya

Prasyarat

Pastikan Anda mengaktifkan Geospatial API sebelum melanjutkan.

Menempatkan anchor Geospasial

Setiap jenis anchor memiliki API khusus untuk membuatnya. Lihat Jenis anchor Geospasial untuk mengetahui informasi selengkapnya.

Membuat anchor dari hit-test

Anda juga dapat membuat anchor Geospasial dari hasil hit-test. Gunakan Pose dari hit-test dan konversikan menjadi GeospatialPose. Gunakan untuk menempatkan salah satu dari 3 jenis anchor yang dijelaskan.

Dapatkan Pose Geospasial dari Pose AR

AREarthManager.Convert(Pose) menyediakan cara tambahan untuk menentukan lintang dan bujur dengan mengonversi Pose AR menjadi Pose Geospasial.

Dapatkan Pose AR dari Pose Geospasial

AREarthManager.Convert(GeospatialPose) mengonversi posisi horizontal, ketinggian, dan rotasi kuarternion yang ditentukan Bumi sehubungan dengan bingkai koordinat timur-atas-selatan menjadi Pose AR sehubungan dengan koordinat dunia GL.

Pilih metode yang sesuai dengan kasus penggunaan Anda

Setiap metode pembuatan anchor memiliki konsekuensi terkait yang perlu diingat:

  • Saat menggunakan Streetscape Geometry, gunakan hit-test untuk melampirkan konten ke bangunan.
  • Lebih suka anchor Medan atau Rooftop daripada anchor WGS84 karena menggunakan nilai ketinggian yang ditentukan oleh Google Maps.

Menentukan lintang dan bujur suatu lokasi

Ada tiga cara untuk menghitung lintang dan bujur suatu lokasi:

  • Gunakan Geospatial Creator untuk melihat dan memperkaya dunia dengan konten 3D tanpa harus pergi ke suatu lokasi secara fisik. Dengan begitu, Anda dapat menempatkan konten imersif 3D secara visual menggunakan peta Google di Unity Editor. Lintang, bujur, rotasi, dan ketinggian konten akan dihitung secara otomatis untuk Anda.
  • Gunakan Google Maps
  • Gunakan Google Earth. Perhatikan bahwa memperoleh koordinat ini menggunakan Google Earth, berbeda dengan Google Maps, akan memberikan margin kesalahan hingga beberapa meter.
  • Pergi ke lokasi fisik

Gunakan Google Maps

Untuk mendapatkan lintang dan bujur lokasi menggunakan Google Maps:

  1. Buka Google Maps di komputer desktop.

  2. Buka Lapisan > Lainnya.

  3. Ubah Jenis Peta menjadi Satelit dan hapus centang pada kotak Tampilan Globe di sudut kiri bawah layar.

    Tindakan ini akan memaksa penggunaan perspektif 2D dan menghilangkan kemungkinan kesalahan yang dapat muncul dari tampilan 3D sudut.

  4. Pada peta, klik kanan lokasi dan pilih bujur/lintang untuk menyalinnya ke papan klip.

Gunakan Google Earth

Anda dapat menghitung lintang dan bujur lokasi dari Google Earth dengan mengklik lokasi di UI dan membaca data dari detail penanda letak.

Untuk mendapatkan lintang dan bujur suatu lokasi menggunakan Google Earth:

  1. Buka Google Earth di komputer desktop.

  2. Buka menu tiga garis dan pilih Map Style.

  3. Nonaktifkan tombol Bangunan 3D.

  4. Setelah tombol Bangunan 3D dinonaktifkan, klik ikon pin untuk menambahkan penanda letak di lokasi yang dipilih.

  5. Tentukan project yang akan berisi penanda letak Anda, lalu klik Simpan.

  6. Di kolom Judul untuk penanda letak, masukkan nama untuk penanda letak.

  7. Klik panah kembali di panel project, lalu pilih menu More Actions.

  8. Pilih Ekspor sebagai file KML dari menu.

File KLM melaporkan lintang, bujur, dan ketinggian untuk penanda letak di tag <coordinates> yang dipisahkan dengan koma, sebagai berikut:

<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>

Jangan gunakan lintang dan bujur dari tag <LookAt>, yang menentukan posisi kamera, bukan lokasi.

Pergi ke lokasi fisik

Anda dapat menghitung ketinggian lokasi dengan pergi ke sana secara fisik dan melakukan pengamatan lokal.

Mendapatkan kuaternion rotasi

GeospatialPose.EunRotation mengekstrak orientasi dari Pose Geospasial dan menghasilkan kuarternion yang mewakili matriks rotasi yang mengubah vektor dari target ke sistem koordinat timur-atas-north (EUN). X+ menunjuk ke timur, Y+ mengarah ke atas dari gravitasi, dan Z+ mengarah ke utara.

Angkur WGS84

Anchor WGS84 adalah jenis anchor yang memungkinkan Anda menempatkan konten 3D pada lintang, bujur, dan ketinggian tertentu. Tema ini bergantung pada Pose dan orientasi untuk ditempatkan di dunia nyata. Posisi terdiri dari lintang, bujur, dan ketinggian, yang ditetapkan dalam sistem koordinat WGS84. Orientasi terdiri dari rotasi kuarternion.

Ketinggian dilaporkan dalam meter di atas elipsoid WGS84 referensi sehingga permukaan tanah tidak berada pada nol. Aplikasi Anda bertanggung jawab menyediakan koordinat ini untuk setiap anchor yang dibuat.

Tempatkan anchor WGS84 di dunia nyata

Menentukan ketinggian suatu lokasi

Ada beberapa cara untuk menentukan ketinggian lokasi untuk menempatkan anchor:

  • Jika lokasi anchor secara fisik berada di dekat pengguna, Anda dapat menggunakan ketinggian yang mirip dengan ketinggian perangkat pengguna.
  • Setelah memiliki lintang dan bujur, gunakan Elevation API untuk mendapatkan elevasi berdasarkan spesifikasi EGM96. Anda harus mengonversi elevasi Maps API EGM96 ke WGS84 untuk perbandingan dengan ketinggian GeospatialPose. Lihat GeoidEval yang memiliki command line dan antarmuka HTML. Maps API melaporkan lintang dan bujur sesuai dengan spesifikasi WGS84 secara langsung.
  • Anda bisa mendapatkan lintang, bujur, dan ketinggian lokasi dari Google Earth. Tindakan ini akan memberi Anda margin error hingga beberapa meter. Gunakan lintang, bujur, dan ketinggian dari tag <coordinates>, bukan tag <LookAt>, di file KML.
  • Jika anchor yang ada berada di dekat dan jika Anda tidak berada pada lereng curam, Anda mungkin dapat menggunakan ketinggian dari GeospatialPose kamera tanpa menggunakan sumber lain, seperti Maps API.

Membuat anchor

Setelah memiliki kuarternion lintang, bujur, ketinggian, dan rotasi, gunakan ARAnchorManagerExtensions.AddAnchor() untuk menambatkan konten ke koordinat geografis yang Anda tentukan.

if (earthTrackingState == TrackingState.Tracking)
{
  var anchor =
      AnchorManager.AddAnchor(
          latitude,
          longitude,
          altitude,
          quaternion);
  var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}

Angkur Medan

Anchor Medan adalah jenis anchor yang memungkinkan Anda menempatkan objek AR hanya menggunakan garis lintang dan bujur, yang memanfaatkan informasi dari VPS untuk menemukan ketinggian yang akurat di atas permukaan tanah.

Alih-alih memasukkan ketinggian yang diinginkan, Anda memberikan ketinggian di atas medan. Jika ini adalah nol, jangkar akan sejajar dengan medan.

Menyetel mode pencarian pesawat

Penemuan bidang bersifat opsional dan tidak diperlukan untuk menggunakan anchor. Perhatikan bahwa hanya bidang horizontal yang digunakan. Bidang horizontal akan membantu penyelarasan dinamis jangkar medan di tanah.

Perhatikan bahwa anchor medan dipengaruhi oleh Horizontal dan Horizontal | Vertical

Gunakan menu drop-down Detection Mode untuk menetapkan mode deteksi:

Membuat Anchor Medan menggunakan Async API baru

Untuk membuat dan menempatkan anchor Medan, panggil ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync().

Anchor tidak akan langsung siap dan perlu diselesaikan. Setelah masalah tersebut diselesaikan, masalah akan tersedia di ResolveAnchorOnTerrainPromise.

public GameObject TerrainAnchorPrefab;

public void Update()
{
    ResolveAnchorOnTerrainPromise terrainPromise =
        AnchorManager.ResolveAnchorOnTerrainAsync(
            latitude, longitude, altitudeAboveTerrain, eunRotation);

    // The anchor will need to be resolved.
    StartCoroutine(CheckTerrainPromise(terrainPromise));
}

private IEnumerator CheckTerrainPromise(ResolveAnchorOnTerrainPromise promise)
{
    yield return promise;

    var result = promise.Result;
    if (result.TerrainAnchorState == TerrainAnchorState.Success &&
        result.Anchor != null)
    {
        // resolving anchor succeeded
        GameObject anchorGO = Instantiate(TerrainAnchorPrefab,
            result.Anchor.gameObject.transform);
        anchorGO.transform.parent = result.Anchor.gameObject.transform;
    }
    else
    {
       // resolving anchor failed
    }

    yield break;
}

Memeriksa Status Promise

Promise akan memiliki PromiseState terkait.

Negara Bagian Deskripsi
Pending Operasi masih tertunda.
Done Operasi selesai dan hasilnya tersedia.
Cancelled Operasi telah dibatalkan.

Memeriksa status jangkar Medan dari hasil Promise

TerrainAnchorState termasuk dalam operasi asinkron dan merupakan bagian dari hasil Promise akhir.

switch (result.TerrainAnchorState)
{
    case TerrainAnchorState.Success:
        // Anchor has successfully resolved
        break;
    case TerrainAnchorState.ErrorUnsupportedLocation:
        // The requested anchor is in a location that isn't supported by the Geospatial API.
        break;
    case TerrainAnchorState.ErrorNotAuthorized:
        // An error occurred while authorizing your app with the ARCore API. See
        // https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
        // for troubleshooting steps.
        break;
    case TerrainAnchorState.ErrorInternal:
        // The Terrain anchor could not be resolved due to an internal error.
        break;
    default:
        break;
}

Angkur Atap

Pahlawan Anchor atap

Jangkar atap adalah jenis jangkar dan sangat mirip dengan Jangkar medan di atas. Perbedaannya adalah Anda akan memberikan ketinggian di atas atap, bukan ketinggian di atas medan.

Membuat anchor atap menggunakan Async API baru

Anchor tidak akan langsung siap dan perlu diselesaikan.

Untuk membuat dan menempatkan anchor atap, panggil ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync(). Demikian pula dengan anchor Medan, Anda juga akan mengakses PromiseState dari Promise. Kemudian, Anda dapat memeriksa hasil Promise untuk mengakses RooftopAnchorState.

public GameObject RooftopAnchorPrefab;

public void Update()
{
    ResolveAnchorOnRooftopPromise rooftopPromise =
        AnchorManager.ResolveAnchorOnRooftopAsync(
            latitude, longitude, altitudeAboveRooftop, eunRotation);

    // The anchor will need to be resolved.
    StartCoroutine(CheckRooftopPromise(rooftopPromise));
}

private IEnumerator CheckRooftopPromise(ResolveAnchorOnTerrainPromise promise)
{
    yield return promise;

    var result = promise.Result;
    if (result.RooftopAnchorState == RooftopAnchorState.Success &&
        result.Anchor != null)
    {
        // resolving anchor succeeded
        GameObject anchorGO = Instantiate(RooftopAnchorPrefab,
            result.Anchor.gameObject.transform);
        anchorGO.transform.parent = result.Anchor.gameObject.transform;
    }
    else
    {
       // resolving anchor failed
    }

    yield break;
}

Memeriksa Status Promise

Promise akan memiliki PromiseState terkait, lihat tabel di atas.

Memeriksa status anchor atap dari hasil Promise

RooftopAnchorState termasuk dalam operasi asinkron dan merupakan bagian dari hasil Promise akhir.

switch (result.RooftopAnchorState)
{
    case TerrainAnchorState.Success:
        // Anchor has successfully resolved
        break;
    case RooftopAnchorState.ErrorUnsupportedLocation:
        // The requested anchor is in a location that isn't supported by the Geospatial API.
        break;
    case RooftopAnchorState.ErrorNotAuthorized:
        // An error occurred while authorizing your app with the ARCore API. See
        // https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
        // for troubleshooting steps.
        break;
    case RooftopAnchorState.ErrorInternal:
        // The Rooftop anchor could not be resolved due to an internal error.
        break;
    default:
        break;
}

Langkah berikutnya