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

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

ประเภทของหมุดยึดตำแหน่งทางภูมิศาสตร์

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

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

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

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

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

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

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

วางหมุดภูมิสารสนเทศ

หมุดแต่ละประเภทมี API เฉพาะสำหรับสร้าง โปรดดูข้อมูลเพิ่มเติมที่ประเภทของหมุดพิกัดภูมิศาสตร์

สร้างจุดยึดจากการทดสอบการคลิก

นอกจากนี้ คุณยังสร้างหมุดตำแหน่งทางภูมิศาสตร์จากผลการทดสอบ Hit Test ได้ด้วย ใช้ท่าทางจาก Hit-Test และแปลงเป็น GeospatialPose ใช้เพื่อวางจุดยึด 1 ใน 3 ประเภทที่อธิบายไว้

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

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

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

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

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

การสร้างหมุดแต่ละวิธีมีข้อดีข้อเสียที่ควรคำนึงถึง ดังนี้

  • เมื่อใช้เรขาคณิตของสภาพแวดล้อมบนท้องถนน ให้ใช้ Hit-Test เพื่อแนบเนื้อหากับอาคาร
  • แนะนำให้ใช้จุดยึดบนพื้นดินหรือบนหลังคาแทนจุดยึด WGS84 เนื่องจากใช้ค่าระดับความสูงที่ Google Maps กำหนด

ระบุละติจูดและลองจิจูดของสถานที่

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

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

ใช้ 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 มิติเป็นปิด

  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

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

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

วางหมุด WGS84 ในโลกแห่งความเป็นจริง

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

การกำหนดระดับความสูงของสถานที่เพื่อวางหมุดมี 2 วิธีดังนี้

  • หากตำแหน่งของจุดยึดอยู่ใกล้กับผู้ใช้ คุณสามารถใช้ระดับความสูงที่คล้ายกับระดับความสูงของอุปกรณ์ของผู้ใช้
  • เมื่อทราบละติจูดและลองจิจูดแล้ว ให้ใช้ Elevation API เพื่อรับระดับความสูงตามข้อกำหนด EGM96 คุณต้องแปลงระดับความสูง EGM96 ของ Maps API เป็น WGS84 เพื่อเปรียบเทียบกับระดับความสูง GeospatialPose ดู GeoidEval ที่มีทั้งบรรทัดคำสั่งและอินเทอร์เฟซ HTML Maps 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);
}

หมุดยึดภูมิประเทศ

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

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

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

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

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

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

สร้างหมุดเทอร์เรนโดยใช้ Async API ใหม่

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

หมุดจะไม่พร้อมใช้งานในทันทีและจำเป็นต้องแก้ไข เมื่อแก้ไขแล้ว รายการจะแสดงใน 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;
}

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

สัญญาจะมี PromiseState ที่เชื่อมโยงอยู่

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

ตรวจสอบสถานะการยึดตามภูมิประเทศของผลลัพธ์ของ 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 บนดาดฟ้า

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

สร้างหมุดบนหลังคาโดยใช้ Async API ใหม่

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

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

ตรวจสอบสถานะการยึดหลังคาของผลลัพธ์ของ 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;
}

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