unity3d 尝试 基于地理定位的 增强现实

来源:互联网 发布:淘宝模特多少钱一个月 编辑:程序博客网 时间:2024/05/14 04:37

首先说,这个尝试失败,属于死在去医院的路上那种。


基于地理定位的增强现实,AR全息实景,是一种高大上的说法,说直白点就是山寨类似随便走这样的应用。

打开应用,搜索周边信息,然后再把信息叠加在摄像头拍摄到的内容上面。



思路:用手机移动来控制unity中的camrea,将摄像头拍摄到的内容作为背景。获取地理信息,将信息转化成文字添加到unity的世界中。


1、用手机移动控制unity中的camrea。

这段代码中unity的论坛中找到,但是时间很久远,改了下发现能用。

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_EDITORprint("NO GYRO");#endif}}public void Update (){if (gyroBool) {Quaternion quatMap;#if UNITY_IOSquatMap = gyro.attitude;#elif UNITY_ANDROIDquatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);#endiftransform.localRotation = quatMap * rotFix;}}}


2、背景摄像头显示摄像机内容

摄像头的内容可以显示在guitexure上也可以显示在plan上,但是在guitexrue上显示的时候,方向转了90度,最后只好显示在plan上。

using UnityEngine;using System.Collections;public class WebCamManager : MonoBehaviour {// Use this for initializationvoid Start () {WebCamTexture webcamTexture = new WebCamTexture ();//如果有后置摄像头,调用后置摄像头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、调用高德地图的地理定位和搜索附近

详细内容请看我之前的博客

http://blog.csdn.net/wuyt2008/article/details/50774017

http://blog.csdn.net/wuyt2008/article/details/50789423


4、当搜索到内容以后,将名称信息添加到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、这个时候显示内容没问题,但是方向会偏移。于是加了个指南针来矫正方向

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 framevoid Update () {transform.rotation = Quaternion.Euler(0, cam.eulerAngles.y-Input.compass.trueHeading, 0);}}


6、最后遇到的,我无法解决的问题

简单一句话,就是滤波。这个应用需要准确稳定的判断出当前手机方向位置状态,但是,输入的内容,重力,罗盘,加速度都是在不断变化,并且会有偏移的量,需要滤波。

虽然大致知道了是应该用互补滤波和卡尔曼滤波,但是,我的水平只能看懂名字,看不懂内容。

数学无力的我只好放弃。等遇到别人写好的代码再抄下吧。


这是死在半路上的结果的样子




这样的结果呢,当然是不甘心的,但是没时间去仔细研究这个问题了,所以只好放弃。如果哪位大侠知道怎么根据重力,罗盘,加速判断手机状态的,在这里跪求先。

源码和编译的apk:http://download.csdn.net/detail/wuyt2008/9458508

0 0
原创粉丝点击