当前位置:   article > 正文

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

增强现实地图实例

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


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

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



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


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

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

http://forum.unity3d.com/threads/sharing-gyroscope-controlled-camera-on-iphone-4.98828/

  1. using UnityEngine;
  2. using System.Collections;
  3. public class CameraManager : MonoBehaviour {
  4. private bool gyroBool;
  5. private Gyroscope gyro;
  6. private Quaternion rotFix;
  7. public void Start ()
  8. {
  9. Transform currentParent = transform.parent;
  10. GameObject camParent = new GameObject ("GyroCamParent");
  11. camParent.transform.position = transform.position;
  12. transform.parent = camParent.transform;
  13. GameObject camGrandparent = new GameObject ("GyroCamGrandParent");
  14. camGrandparent.transform.position = transform.position;
  15. camParent.transform.parent = camGrandparent.transform;
  16. camGrandparent.transform.parent = currentParent;
  17. gyroBool = SystemInfo.supportsGyroscope;
  18. if (gyroBool) {
  19. gyro = Input.gyro;
  20. gyro.enabled = true;
  21. if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
  22. camParent.transform.eulerAngles = new Vector3 (90, 90, 0);
  23. } else if (Screen.orientation == ScreenOrientation.Portrait) {
  24. camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
  25. } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
  26. camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
  27. } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
  28. camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
  29. } else {
  30. camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
  31. }
  32. if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
  33. rotFix = new Quaternion (0, 0,0.7071f,0.7071f);
  34. } else if (Screen.orientation == ScreenOrientation.Portrait) {
  35. rotFix = new Quaternion (0, 0, 1, 0);
  36. } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
  37. rotFix = new Quaternion (0, 0, 1, 0);
  38. } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
  39. rotFix = new Quaternion (0, 0, 1, 0);
  40. } else {
  41. rotFix = new Quaternion (0, 0, 1, 0);
  42. }
  43. //Screen.sleepTimeout = 0;
  44. } else {
  45. #if UNITY_EDITOR
  46. print("NO GYRO");
  47. #endif
  48. }
  49. }
  50. public void Update ()
  51. {
  52. if (gyroBool) {
  53. Quaternion quatMap;
  54. #if UNITY_IOS
  55. quatMap = gyro.attitude;
  56. #elif UNITY_ANDROID
  57. quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
  58. #endif
  59. transform.localRotation = quatMap * rotFix;
  60. }
  61. }
  62. }


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

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

  1. using UnityEngine;
  2. using System.Collections;
  3. public class WebCamManager : MonoBehaviour {
  4. // Use this for initialization
  5. void Start () {
  6. WebCamTexture webcamTexture = new WebCamTexture ();
  7. //如果有后置摄像头,调用后置摄像头
  8. for (int i = 0; i < WebCamTexture.devices.Length; i++) {
  9. if (!WebCamTexture.devices [i].isFrontFacing) {
  10. webcamTexture.deviceName = WebCamTexture.devices [i].name;
  11. break;
  12. }
  13. }
  14. Renderer renderer = GetComponent<Renderer>();
  15. renderer.material.mainTexture = webcamTexture;
  16. webcamTexture.Play();
  17. }
  18. }


3、调用高德地图的地理定位和搜索附近

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

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

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


4、当搜索到内容以后,将名称信息添加到unity的世界里。

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine.UI;
  5. public class ARMange : MonoBehaviour {
  6. public List<PlaceInfo> places = new List<PlaceInfo>();
  7. public GameObject perfab;
  8. public PlaceInfo location = new PlaceInfo ();
  9. public void ShowPlaces(){
  10. ClearPlace ();
  11. for (int i = 0; i < places.Count; i++) {
  12. GameObject newPlace = Instantiate<GameObject> (perfab);
  13. newPlace.transform.parent = this.transform;
  14. double posZ = places [i].Latitude - location.Latitude;
  15. double posX = places [i].Longitude - location.Longitude;
  16. float z = 0;
  17. float x = 0;
  18. float y = 0;
  19. if (posZ > 0) {
  20. z = 500f;
  21. } else {
  22. z = -500f;
  23. }
  24. if (posX > 0) {
  25. x = 500f;
  26. } else {
  27. x = -500f;
  28. }
  29. z = z + (float)(posZ * 1000);
  30. x = x + (float)(posX * 1000);
  31. y = y + i * 20;
  32. newPlace.transform.position = new Vector3 (x, y, z);
  33. newPlace.transform.LookAt (this.transform);
  34. newPlace.transform.Rotate (new Vector3 (0f, 180f, 0f));
  35. newPlace.gameObject.GetComponentInChildren<Text> ().text = places [i].Name;
  36. }
  37. }
  38. private void ClearPlace(){
  39. GameObject[] oldPlaces = GameObject.FindGameObjectsWithTag ("Place");
  40. for (int i = 0; i < oldPlaces.Length; i++) {
  41. Destroy (oldPlaces [i].gameObject);
  42. }
  43. }
  44. }


5、这个时候显示内容没问题,但是方向会偏移。于是加了个指南针来矫正方向

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.UI;
  4. public class CompassManage : MonoBehaviour {
  5. public Transform cam;
  6. void Start () {
  7. Input.location.Start ();
  8. Input.compass.enabled = true;
  9. }
  10. // Update is called once per frame
  11. void Update () {
  12. transform.rotation = Quaternion.Euler(0, cam.eulerAngles.y-Input.compass.trueHeading, 0);
  13. }
  14. }


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

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

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

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


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




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

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

====================



在SearchManage.cs文件中,我把搜索范围限定在了昆明,

  1. //txtInfo.text = txtInfo.text + "\r\n";
  2. AndroidJavaObject query = amapHelper.Call<AndroidJavaObject>("getPoiSearch",inputQuery.text,"","0871");
  3. txtInfo.text = txtInfo.text + "query get...";
将0871改成其他地方的区号就可以了,(为空是全国范围,但是没验证过)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/118067
推荐阅读
相关标签
  

闽ICP备14008679号