ใช้ Geospatial Anchor เพื่อกำหนดตำแหน่งเนื้อหาในโลกจริงบน Unity

จุดยึดทางภูมิศาสตร์เป็นสมอประเภทหนึ่งที่ช่วยให้คุณสามารถวางเนื้อหา 3 มิติในโลกแห่งความเป็นจริง

ประเภทของจุดยึดภูมิสารสนเทศ

จุดยึดภูมิสารสนเทศมี 3 ประเภท ซึ่งแต่ละจุดระดับความสูงของแฮนเดิลมีลักษณะแตกต่างกัน ดังนี้

  1. แท็ก Anchor WGS84:
    แท็ก Anchor WGS84 จะช่วยให้คุณวางเนื้อหา 3 มิติในละติจูด ลองจิจูด และระดับความสูงที่ระบุได้

  2. การตรึงภูมิประเทศ:
    จุดยึดภูมิประเทศช่วยให้คุณวางเนื้อหาโดยใช้ละติจูดและลองจิจูดที่มีความสูงสัมพันธ์กับภูมิประเทศที่ตำแหน่งนั้นได้เท่านั้น ระดับความสูงจะกำหนดโดยสัมพันธ์กับพื้นหรือชั้นดังที่ VPS ทราบ

  3. พุกบนชั้นดาดฟ้า:
    พุกบนชั้นดาดฟ้าช่วยให้คุณวางเนื้อหาได้โดยใช้ละติจูดและลองจิจูดที่มีความสูงสัมพัทธ์กับหลังคาของอาคารที่ตำแหน่งนั้นๆ ระดับความสูงจะถูกกำหนดโดยสัมพันธ์กับด้านบนของอาคารตามที่เรขาคณิตของ Streetscape รู้จัก ตัวเลือกนี้จะมีค่าเริ่มต้นเป็นระดับความสูงของภูมิประเทศเมื่อไม่ได้วางบนสิ่งปลูกสร้าง

WGS84 ภูมิประเทศ ติดหลังคา
ตำแหน่งแนวนอน ละติจูด ลองจิจูด ละติจูด ลองจิจูด ละติจูด ลองจิจูด
ตำแหน่งแนวตั้ง สัมพัทธ์กับระดับความสูง WGS84 สัมพันธ์กับระดับภูมิประเทศที่กำหนดโดย Google Maps สัมพันธ์กับชั้นดาดฟ้าที่กำหนดโดย Google Maps
จำเป็นต้องได้รับการแก้ไขจากเซิร์ฟเวอร์ไหม ไม่ได้ มี มี

ข้อกำหนดเบื้องต้น

ตรวจสอบว่าคุณเปิดใช้ Geospatial API ก่อนดำเนินการต่อ

วางจุดยึดภูมิสารสนเทศ

แท็ก Anchor แต่ละประเภทจะมี API เฉพาะสําหรับสร้าง โปรดดูประเภทของจุดยึดเชิงพื้นที่สําหรับข้อมูลเพิ่มเติม

สร้างการตรึงจากการทดสอบ Hit

นอกจากนี้ คุณยังสร้าง Geospatial Anchor จากผลการทดสอบ Hit ได้ด้วย ใช้ท่าทางจากการทดสอบ Hit และแปลงเป็น GeospatialPose ใช้เพื่อวาง Anchor ประเภทใดก็ได้ใน 3 ประเภทที่อธิบายไว้

รับท่าทางภูมิสารสนเทศจากท่า AR

AREarthManager.Convert(Pose) เป็นวิธีเพิ่มเติมในการกำหนดละติจูดและลองจิจูดด้วยการแปลงตำแหน่ง AR เป็นตำแหน่งทางภูมิศาสตร์

ทำท่า AR จากท่าภูมิสารสนเทศ

AREarthManager.Convert(GeospatialPose) แปลงตำแหน่งแนวนอน ระดับความสูง และการหมุนควอเทอร์เนียนที่ระบุโลกตามเฟรมพิกัดแบบตะวันออก-ใต้เป็นจุด AR ตามพิกัดโลกของ GL

เลือกวิธีที่เหมาะกับกรณีการใช้งานของคุณ

การสร้างแท็ก Anchor แต่ละวิธีมีข้อดีข้อเสียที่เกี่ยวข้องที่ควรทราบ ดังนี้

  • เมื่อใช้ Streetscape Geometry ให้ใช้การทดสอบ Hit เพื่อแนบเนื้อหากับอาคาร
  • เลือกใช้ Anchor ภูมิประเทศหรือ Rooftop มากกว่า Anchor ของ WGS84 เพราะใช้ค่าระดับความสูงที่ Google Maps กำหนด

กำหนดละติจูดและลองจิจูดของสถานที่

การคำนวณละติจูดและลองจิจูดของสถานที่ทำได้ 3 วิธีดังนี้

  • ใช้ผู้สร้างภูมิสารสนเทศเพื่อดูและขยายโลกด้วยเนื้อหา 3 มิติโดยไม่ต้องไปยังสถานที่ใดก็ตาม ซึ่งช่วยให้คุณวางเนื้อหาที่สมจริงแบบ 3 มิติได้โดยใช้ Google Maps ในเครื่องมือแก้ไข Unity ระบบจะคำนวณละติจูด ลองจิจูด การหมุน และระดับความสูงของเนื้อหาให้คุณโดยอัตโนมัติ
  • ใช้ Google Maps
  • ใช้ Google Earth โปรดทราบว่าการได้รับพิกัดเหล่านี้โดยใช้ Google Earth ซึ่งตรงข้ามกับ Google แผนที่จะทำให้คลาดเคลื่อนได้คลาดเคลื่อนไปหลายเมตร
  • ไปที่สถานที่ตั้งจริง

ใช้ Google Maps

วิธีดูละติจูดและลองจิจูดของสถานที่โดยใช้ Google Maps

  1. ไปที่ Google Maps บนคอมพิวเตอร์เดสก์ท็อป

  2. ไปที่เลเยอร์ > เพิ่มเติม

  3. เปลี่ยนประเภทแผนที่เป็นดาวเทียม และล้างช่องทำเครื่องหมายมุมมองแบบโลกที่มุมซ้ายล่างของหน้าจอ

    ซึ่งจะเป็นการผลักดันมุมมอง 2 มิติและกำจัดข้อผิดพลาดที่อาจมาจากมุมมอง 3 มิติแบบมุมฉาก

  4. บนแผนที่ ให้คลิกขวาที่สถานที่และเลือกลองจิจูด/ละติจูดเพื่อคัดลอกไปที่คลิปบอร์ดของคุณ

ใช้ Google Earth

คุณสามารถคำนวณละติจูดและลองจิจูดของสถานที่จาก Google Earth ได้โดยคลิกสถานที่ใน UI และอ่านข้อมูลจากรายละเอียดหมุด

หากต้องการทราบละติจูดและลองจิจูดของสถานที่โดยใช้ Google Earth ให้ทำดังนี้

  1. ไปที่ Google Earth บนคอมพิวเตอร์เดสก์ท็อป

  2. ไปที่เมนู 3 ขีด แล้วเลือกรูปแบบแผนที่

  3. ปิดสวิตช์สิ่งปลูกสร้าง 3 มิติ

  4. เมื่อปิดสวิตช์สิ่งปลูกสร้าง 3 มิติแล้ว ให้คลิกไอคอนหมุด เพื่อเพิ่มหมุดตรงตำแหน่งที่เลือก

  5. ระบุโครงการที่จะมีหมุดของคุณ แล้วคลิกบันทึก

  6. ในช่องชื่อของหมุด ให้ป้อนชื่อของหมุด

  7. คลิกลูกศรย้อนกลับ ในแผงโครงการ แล้วเลือกเมนูการทำงานเพิ่มเติมของ

  8. เลือกส่งออกเป็นไฟล์ KML จากเมนู

ไฟล์ KLM จะรายงานละติจูด ลองจิจูด และระดับความสูงของหมุดในแท็ก <coordinates> ที่คั่นด้วยเครื่องหมายจุลภาค ดังนี้

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

อย่าใช้ละติจูดและลองจิจูดจากแท็ก <LookAt> ซึ่งระบุตำแหน่งของกล้อง ไม่ใช่ตำแหน่ง

ไปที่สถานที่ตั้งจริง

คุณสามารถคำนวณระดับความสูงของสถานที่โดยการไปที่สถานที่ตั้งนั้นทางกายภาพและสังเกตการณ์ในท้องถิ่น

รับควอเทอร์เนียนการหมุน

GeospatialPose.EunRotation จะแยกการวางแนวจากท่าทางภูมิสารสนเทศและเอาต์พุตเป็นควอเทิร์นที่แสดงเมทริกซ์การหมุนที่เปลี่ยนรูปแบบเวกเตอร์จากเป้าหมายเป็นระบบพิกัดแบบตะวันออก-ขึ้น-เหนือ (EUN) จุด X+ ทิศตะวันออก จุด Y+ ชี้ขึ้นจากแรงโน้มถ่วง และจุด Z+ ชี้ขึ้นทิศเหนือ

พุก WGS84

แท็ก Anchor WGS84 คือจุดยึดประเภทหนึ่งที่ช่วยให้คุณวางเนื้อหา 3 มิติไว้ที่ละติจูด ลองจิจูด และระดับความสูงหนึ่งๆ ได้ ภาพจะอาศัยการโพสท่าและการวางแนวเพื่อวางในโลกจริง ตำแหน่งประกอบด้วยละติจูด ลองจิจูด และระดับความสูงตามที่ระบุไว้ในระบบพิกัด WGS84 การวางแนวประกอบด้วยการหมุนควอเทอร์เนียน

ระดับความสูงจะมีการรายงานเป็นหน่วยเมตรเหนือวงรีอ้างอิง WGS84 ดังนั้นระดับพื้นดินจะไม่เท่ากับ 0 แอปของคุณมีหน้าที่ในการให้พิกัดเหล่านี้สำหรับแท็ก Anchor แต่ละรายการที่สร้างขึ้น

วางสมอเรือ WGS84 ในชีวิตจริง

ระบุระดับความสูงของสถานที่

การระบุระดับความสูงของสถานที่สำหรับวาง Anchor ทำได้หลายวิธี ดังนี้

  • หากตำแหน่งของ Anchor อยู่ใกล้กับผู้ใช้ คุณจะใช้ระดับความสูงที่คล้ายกับระดับความสูงของอุปกรณ์ของผู้ใช้ได้
  • เมื่อทราบละติจูดและลองจิจูดแล้ว ให้ใช้ Elevation API เพื่อรับระดับความสูงตามข้อกำหนดของ EGM96 คุณต้องแปลงระดับความสูงของ Maps API EGM96 เป็น WGS84 เพื่อเปรียบเทียบกับระดับความสูง GeospatialPose โปรดดู GeoidEval ที่มีทั้งบรรทัดคำสั่งและอินเทอร์เฟซ HTML แผนที่ API จะรายงานละติจูดและลองจิจูดตามข้อกำหนดของ WGS84 ในทันที
  • คุณรับข้อมูลละติจูด ลองจิจูด และระดับความสูงของสถานที่ได้จาก Google Earth ซึ่งจะทำให้คลาดเคลื่อนไปได้หลายเมตร ใช้ละติจูด ลองจิจูด และระดับความสูงจากแท็ก <coordinates> ไม่ใช่แท็ก <LookAt> ในไฟล์ KML
  • หากจุดยึดที่มีอยู่อยู่ใกล้และหากคุณไม่ได้อยู่บนทางลาดชัน คุณอาจใช้ระดับความสูงจาก GeospatialPose ของกล้องได้โดยไม่ต้องใช้แหล่งที่มาอื่น เช่น Maps API

สร้าง Anchor

เมื่อมีละติจูด ลองจิจูด ระดับความสูง และการหมุน ให้ใช้ ARAnchorManagerExtensions.AddAnchor() เพื่อตรึงเนื้อหากับพิกัดทางภูมิศาสตร์ที่คุณระบุ

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

ตัวยึดภูมิประเทศ

แท็ก Anchor ภูมิประเทศเป็นสมอประเภทหนึ่งที่ช่วยให้คุณสามารถวางวัตถุ AR โดยใช้เฉพาะละติจูดและลองจิจูด โดยใช้ประโยชน์จากข้อมูลจาก VPS เพื่อค้นหาระดับความสูงเหนือพื้นดิน

คุณจะระบุระดับความสูงเหนือภูมิประเทศแทนการป้อนระดับความสูงที่ต้องการ เมื่อเป็นศูนย์ จุดยึดจะอยู่ในระดับเดียวกับภูมิประเทศ

ตั้งค่าโหมดหาเครื่องบิน

การค้นหาระนาบเป็นตัวเลือกที่ไม่บังคับและไม่จำเป็นต้องใช้จุดยึด โปรดทราบว่าระบบจะใช้เฉพาะระนาบแนวนอนเท่านั้น ระนาบแนวนอนจะช่วยในการปรับทิศทางแบบไดนามิกของจุดยึดภูมิประเทศบนพื้น

โปรดทราบว่า Horizontal และ Horizontal | Vertical จะได้รับผลกระทบจากจุดยึดภูมิประเทศ

ใช้เมนูแบบเลื่อนลงของโหมดตรวจจับเพื่อตั้งค่าโหมดการตรวจจับ ดังนี้

สร้าง Anchor ภูมิประเทศโดยใช้ Async API ใหม่

หากต้องการสร้างและวาง Anchor ภูมิประเทศ ให้เรียก ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync()

แท็ก Anchor จะไม่พร้อมใช้งานในทันทีและจำเป็นต้องแก้ไข เมื่อแก้ไขแล้ว คุณจะมีสิทธิ์เข้าถึงใน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;
}

ตรวจสอบสถานะสัญญา

The Promise จะมี PromiseState เชื่อมโยงอยู่

รัฐ คำอธิบาย
Pending รอการดำเนินการอยู่
Done การดำเนินการเสร็จสมบูรณ์และผลลัพธ์พร้อมใช้งาน
Cancelled ยกเลิกการดำเนินการแล้ว

ตรวจสอบสถานะ Anchor ภูมิประเทศของผลลัพธ์ Promise

TerrainAnchorState เป็นของการดำเนินการแบบอะซิงโครนัสและเป็นส่วนหนึ่งของผลลัพธ์ Promise ขั้นสุดท้าย

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;
}

พุกยึดหลังคา

ฮีโร่ติดหลังคา

พุกยึดหลังคาเป็นพุกประเภทหนึ่งและคล้ายกับจุดยึดภูมิประเทศที่อยู่ด้านบนเป็นอย่างมาก สิ่งที่แตกต่างคือ คุณจะระบุระดับความสูงเหนือพื้นดิน แทนที่จะเป็นระดับความสูงเหนือภูมิประเทศ

สร้าง Anchor ของ Rooftop โดยใช้ Async API ใหม่

แท็ก Anchor จะไม่พร้อมใช้งานในทันทีและจำเป็นต้องแก้ไข

หากต้องการสร้างและวาง Anchor ของ Rooftop ให้เรียกใช้ ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync() คุณจะเข้าถึง PromiseState of the Promise ได้เช่นกัน ในทำนองเดียวกับ Anchors ภูมิประเทศ จากนั้นคุณสามารถตรวจสอบผลลัพธ์ของ Promise เพื่อเข้าถึง 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;
}

ตรวจสอบสถานะสัญญา

คำสัญญาจะมี PromiseState ที่เกี่ยวข้อง โปรดดูตารางด้านบน

ตรวจสอบสถานะ Anchor ของ Rooftop ของผลลัพธ์ Promise

RooftopAnchorState เป็นของการดำเนินการแบบอะซิงโครนัสและเป็นส่วนหนึ่งของผลลัพธ์ Promise ขั้นสุดท้าย

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;
}

ขั้นตอนถัดไป