首先說,這個嘗試失敗,屬于死在去醫(yī)院的路上那種。
基于地理定位的增強現(xiàn)實,AR全息實景,是一種高大上的說法,說直白點就是山寨類似隨便走這樣的應(yīng)用。
打開應(yīng)用,搜索周邊信息,然后再把信息疊加在攝像頭拍攝到的內(nèi)容上面。

思路:用手機移動來控制unity中的camrea,將攝像頭拍攝到的內(nèi)容作為背景。獲取地理信息,將信息轉(zhuǎn)化成文字添加到unity的世界中。
1、用手機移動控制unity中的camrea。
這段代碼中unity的論壇中找到,但是時間很久遠,改了下發(fā)現(xiàn)能用。
http://forum.unity3d.com/threads/sharing-gyroscope-controlled-camera-on-iphone-4.98828/
using UnityEngine;
using System.Collections;
public class CameraManager : MonoBehaviour {
private bool gyroBool;
private Gyroscope gyro;
private Quaternion rotFix;
public void Start ()
{
Transform currentParent = transform.parent;
GameObject camParent = new GameObject ("GyroCamParent");
camParent.transform.position = transform.position;
transform.parent = camParent.transform;
GameObject camGrandparent = new GameObject ("GyroCamGrandParent");
camGrandparent.transform.position = transform.position;
camParent.transform.parent = camGrandparent.transform;
camGrandparent.transform.parent = currentParent;
gyroBool = SystemInfo.supportsGyroscope;
if (gyroBool) {
gyro = Input.gyro;
gyro.enabled = true;
if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
camParent.transform.eulerAngles = new Vector3 (90, 90, 0);
} else if (Screen.orientation == ScreenOrientation.Portrait) {
camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
} else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
} else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
} else {
camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
}
if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
rotFix = new Quaternion (0, 0,0.7071f,0.7071f);
} else if (Screen.orientation == ScreenOrientation.Portrait) {
rotFix = new Quaternion (0, 0, 1, 0);
} else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
rotFix = new Quaternion (0, 0, 1, 0);
} else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
rotFix = new Quaternion (0, 0, 1, 0);
} else {
rotFix = new Quaternion (0, 0, 1, 0);
}
//Screen.sleepTimeout = 0;
} else {
#if UNITY_EDITOR
print("NO GYRO");
#endif
}
}
public void Update ()
{
if (gyroBool) {
Quaternion quatMap;
#if UNITY_IOS
quatMap = gyro.attitude;
#elif UNITY_ANDROID
quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
#endif
transform.localRotation = quatMap * rotFix;
}
}
}
2、背景攝像頭顯示攝像機內(nèi)容
攝像頭的內(nèi)容可以顯示在guitexure上也可以顯示在plan上,但是在guitexrue上顯示的時候,方向轉(zhuǎn)了90度,最后只好顯示在plan上。
using UnityEngine;
using System.Collections;
public class WebCamManager : MonoBehaviour {
// Use this for initialization
void Start () {
WebCamTexture webcamTexture = new WebCamTexture ();
//如果有后置攝像頭,調(diào)用后置攝像頭
for (int i = 0; i < WebCamTexture.devices.Length; i++) {
if (!WebCamTexture.devices [i].isFrontFacing) {
webcamTexture.deviceName = WebCamTexture.devices [i].name;
break;
}
}
Renderer renderer = GetComponent<Renderer>();?
renderer.material.mainTexture = webcamTexture;?
webcamTexture.Play();?
}
}
3、調(diào)用高德地圖的地理定位和搜索附近
詳細內(nèi)容請看我之前的博客
http://blog.csdn.net/wuyt2008/article/details/50774017
http://blog.csdn.net/wuyt2008/article/details/50789423
4、當(dāng)搜索到內(nèi)容以后,將名稱信息添加到unity的世界里。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class ARMange : MonoBehaviour {
public List<PlaceInfo> places = new List<PlaceInfo>();
public GameObject perfab;
public PlaceInfo location = new PlaceInfo ();
public void ShowPlaces(){
ClearPlace ();
for (int i = 0; i < places.Count; i++) {
GameObject newPlace = Instantiate<GameObject> (perfab);
newPlace.transform.parent = this.transform;
double posZ = places [i].Latitude - location.Latitude;
double posX = places [i].Longitude - location.Longitude;
float z = 0;
float x = 0;
float y = 0;
if (posZ > 0) {
z = 500f;
} else {
z = -500f;
}
if (posX > 0) {
x = 500f;
} else {
x = -500f;
}
z = z + (float)(posZ * 1000);
x = x + (float)(posX * 1000);
y = y + i * 20;
newPlace.transform.position = new Vector3 (x, y, z);
newPlace.transform.LookAt (this.transform);
newPlace.transform.Rotate (new Vector3 (0f, 180f, 0f));
newPlace.gameObject.GetComponentInChildren<Text> ().text = places [i].Name;
}
}
private void ClearPlace(){
GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");
for (int i = 0; i < oldPlaces.Length; i++) {
Destroy (oldPlaces [i].gameObject);
}
}
}
5、這個時候顯示內(nèi)容沒問題,但是方向會偏移。于是加了個指南針來矯正方向
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class CompassManage : MonoBehaviour {
public Transform cam;
void Start () {
Input.location.Start ();
Input.compass.enabled = true;
}
// Update is called once per frame
void Update () {
transform.rotation = Quaternion.Euler(0, cam.eulerAngles.y-Input.compass.trueHeading, 0);
}
}
6、最后遇到的,我無法解決的問題
簡單一句話,就是濾波。這個應(yīng)用需要準確穩(wěn)定的判斷出當(dāng)前手機方向位置狀態(tài),但是,輸入的內(nèi)容,重力,羅盤,加速度都是在不斷變化,并且會有偏移的量,需要濾波。
雖然大致知道了是應(yīng)該用互補濾波和卡爾曼濾波,但是,我的水平只能看懂名字,看不懂內(nèi)容。
數(shù)學(xué)無力的我只好放棄。等遇到別人寫好的代碼再抄下吧。
這是死在半路上的結(jié)果的樣子

這樣的結(jié)果呢,當(dāng)然是不甘心的,但是沒時間去仔細研究這個問題了,所以只好放棄。如果哪位大俠知道怎么根據(jù)重力,羅盤,加速判斷手機狀態(tài)的,在這里跪求先。
源碼和編譯的apk:http://download.csdn.net/detail/wuyt2008/9458508
====================
在SearchManage.cs文件中,我把搜索范圍限定在了昆明,
//txtInfo.text = txtInfo.text + "\r\n";
AndroidJavaObject query = amapHelper.Call<AndroidJavaObject>("getPoiSearch",inputQuery.text,"","0871");
txtInfo.text = txtInfo.text + "query get...";
將0871改成其他地方的區(qū)號就可以了,(為空是全國范圍,但是沒驗證過)
原文:https://blog.csdn.net/wuyt2008/article/details/50854262