【Unity3D】AR應用中,關於東南西北方位的判斷。


這篇文章的應用場景是這樣子的:

  首先我們要做的是一個帶有LBS定位服務(比如高德地圖、百度地圖等)AR功能,在這個場景中,會有一些地圖上的”點“(如派出所、學校)是我們需要顯示在我們的AR鏡頭上的,如下圖:

圖片摘自wuyt2008的博客:《unity3d 嘗試 基於地理定位的 增強現實

  本文要解決的問題就是,如何判斷這些Point的東南西北,即坐標。

    博主采用的開發環境是

  1. Unity3D: 5.3.5;
  2. EazyAR: SKD v1.3.0;
  3. GyroDroid :這個Unity3D 的傳感器插件包上網搜一下就有了。

    要應用本博客的內容之前,必須先看過wuyt2008的博客《unity3d 嘗試 基於地理定位的 增強現實》。

    開坑:

  實際上我們要實現功能的原理就是根據定位返回的自身(Location)坐標(XL,ZL),跟我們需要標注顯示出來的Marker的坐標(XM,ZM)進行坐標系的運算,很簡單,

X=XL-XM

Z=ZL-ZM

  然后我們再把我們的主攝像機的Position的x、z軸(Y是控制高的,與物體平面定位沒有關系)設置為(0,0),這樣呢,Marker在Unity中得坐標,就是(X,Z),並且經過我的測試,Unity中在使用ARCamera的情況下,+X軸指的方向是東90°,+Z軸指的方向是北90°。我們根本不需要做任何其他判斷,只需要根據這個特性,再根據經緯度的數據特性,如果X的值為負,則表示Marker位於東邊(相對自身),如果Z的值為負,則表示Marker位於北邊(相對自身),所以只需要按照(-X,-Z)設置Marker的(X,Z)坐標,即可准確的安放Marker的位置。

  首先,我們使用EazyAR SDK 中提供的AR攝像機,為什么說它是AR攝像機呢,因為它本身已經根據AR應用的特性,進行了一些優化,還有添加了一些C# Script,所以直接拿來用,你會發現比你自己寫一大堆亂七八糟的代碼好多了。然后呢,再將GyroDroid插件包中的“MinimalSensorCamera”腳本,綁定到攝像機上,讓AR攝像機鏡頭隨着手機的旋轉而旋轉。

  然后就是最重要的一個環節,這里要結合wuyt2008博主的博客中得代碼來介紹,我把代碼貼一下,並且我自己加了一些注釋,助於觀看:

 1 using UnityEngine;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using UnityEngine.UI;
 5 
 6 public class ARMange : MonoBehaviour {
 7 
 8     public List<PlaceInfo> places = new List<PlaceInfo>();//Marker的集合(Marker是什么,請學習一下高德地圖api的應用,簡單的說,就是你想要標記在地圖上的點,比如一些餐廳或景點之類,甚至可以是自定義的點)
 9     public GameObject perfab;
10     public PlaceInfo location = new PlaceInfo ();//根據高德API定位后傳遞過來的自身坐標信息
11 
12     public void ShowPlaces(){
13         ClearPlace ();
14 
15         for (int i = 0; i < places.Count; i++) {
16 
17             GameObject newPlace = Instantiate<GameObject> (perfab);
18             newPlace.transform.parent = this.transform;
19 
20             double posZ = places [i].Latitude - location.Latitude;//計算相對距離,z軸(Unity中的坐標系)
21             double posX = places [i].Longitude - location.Longitude;//計算相對距離,x軸(Unity中的坐標系)
22 
23             float z = 0;
24             float x = 0;
25             float y = 0;
26 
27             if (posZ > 0) {
28                 z = 500f;
29             } else {
30                 z = -500f;
31             }
32 
33             if (posX > 0) {
34                 x = 500f;
35             } else {
36                 x = -500f;
37             }
38 
39             z = z + (float)(posZ * 1000);
40             x = x + (float)(posX * 1000);
41             y = y + i * 20;
42 
43             newPlace.transform.position = new Vector3 (x, y, z);//設置Marker
44             newPlace.transform.LookAt (this.transform);
45             newPlace.transform.Rotate (new Vector3 (0f, 180f, 0f));
46 
47             newPlace.gameObject.GetComponentInChildren<Text> ().text = places [i].Name;
48         }
49     }
50 
51     private void ClearPlace(){
52         GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");
53         for (int i = 0; i < oldPlaces.Length; i++) {
54             Destroy (oldPlaces [i].gameObject);
55         }
56     }
57 }

  然后我們把Unity3D中,ARCamera(AR攝像機)的Position,設置為(0,0,0)這么做呢,是方便等會兒設定Marker的坐標,只有相機坐標設置為這樣子,X和Z的值才是Marker的直接坐標,否則還得進行一些運算。不過這里值得注意的是,坐標系的設定,應該在CameraDevice對象上,否則是無效的。

  然后我們修改上述的代碼,修改起來,並不會太難,只需要修改第43行,改成:

20 double posZ = places [i].Latitude - location.Latitude;//計算相對距離,z軸(Unity中的坐標系)
21 double posX = places [i].Longitude - location.Longitude;//計算相對距離,x軸(Unity中的坐標系)
43 newPlace.transform.position = new Vector3 (-x, y, -z);//設置Marker

  這樣就完事兒了。。。wuyt2008的博客《unity3d 嘗試 基於地理定位的 增強現實》最后所提及的偏移問題,貌似沒有這種情況,可能是跟EazyAR提供的ARCamera有關,以及鏡頭自動會有東南西北的方向感。最后感謝wuyt2008,最近在做AR的項目CityHunter,一直在研究如何將高德定位整合進Unity3D來,雖然應用方面與其所描述的不太相干(實際上我要運用的是高德API的電子圍欄的功能),但是在操作中可舉一反三,果斷是學習到了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM