转:http://www.manew.com/forum.php?mod=viewthread&tid=50417&page=1&authorid=132510
首先说,这个尝试失败,属于死在去医院的路上那种。
基于地理定位的增强现实,AR全息实景,是一种高大上的说法,说直白点就是山寨类似随便走这样的应用。
打开应用,搜索周边信息,然后再把信息叠加在摄像头拍摄到的内容上面。
思路:用手机移动来控制unity中的camrea,将摄像头拍摄到的内容作为背景。获取地理信息,将信息转化成文字添加到unity的世界中。
1、用手机移动控制unity中的camrea。
这段代码中unity的论坛中找到,但是时间很久远,改了下发现能用。
http://forum.unity3d.com/threads ... -on-iphone-4.98828/
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
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_
quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
#endif
transform.localRotation = quatMap * rotFix;
}
}
}
2、背景摄像头显示摄像机内容
摄像头的内容可以显示在guitexure上也可以显示在plan上,但是在guitexrue上显示的时候,方向转了90度,最后只好显示在plan上。
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
using UnityEngine;
using System.Collections;
public class WebCamManager : MonoBehaviour {
// Use this for initialization
void Start () {
WebCamTexture webcamTexture = new WebCamTexture ();
//如果有后置摄像头,调用后置摄像头
for (int i = 0; i < WebCamTexture.devices.Length; i++) {
if (!WebCamTexture.devices .isFrontFacing) {
webcamTexture.deviceName = WebCamTexture.devices .name;
break;
}
}
Renderer renderer = GetComponent();
renderer.material.mainTexture = webcamTexture;
webcamTexture.Play();
}
}
3、调用高德地图的地理定位和搜索附近
详细内容请看我之前的博客
http://blog.csdn.net/wuyt2008/article/details/50774017
http://blog.csdn.net/wuyt2008/article/details/50789423
4、当搜索到内容以后,将名称信息添加到unity的世界里。
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class ARMange : MonoBehaviour {
public List places = new List();
public GameObject perfab;
public PlaceInfo location = new PlaceInfo ();
public void ShowPlaces(){
ClearPlace ();
for (int i = 0; i < places.Count; i++) {
GameObject newPlace = Instantiate (perfab);
newPlace.transform.parent = this.transform;
double posZ = places .Latitude - location.Latitude;
double posX = places .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 = places .Name;
}
}
private void ClearPlace(){
GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");
for (int i = 0; i < oldPlaces.Length; i++) {
Destroy (oldPlaces .gameObject);
}
}
}
5、这个时候显示内容没问题,但是方向会偏移。于是加了个指南针来矫正方向
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
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、最后遇到的,我无法解决的问题
简单一句话,就是滤波。这个应用需要准确稳定的判断出当前手机方向位置状态,但是,输入的内容,重力,罗盘,加速度都是在不断变化,并且会有偏移的量,需要滤波。
虽然大致知道了是应该用互补滤波和卡尔曼滤波,但是,我的水平只能看懂名字,看不懂内容。
数学无力的我只好放弃。等遇到别人写好的代码再抄下吧。
这是死在半路上的结果的样子