开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

教程分享

关注:606

当前位置:游戏蛮牛 技术专区 教程分享

查看: 1608|回复: 7

[基础知识] Unity3D尝试 基于地理定位的 增强现实

[复制链接]  [移动端链接]
7日久生情
4001/5000
排名
2308
昨日变化

1547

主题

1557

帖子

4001

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
132510
好友
17
蛮牛币
42402
威望
0
注册时间
2015-12-24
在线时间
324 小时
最后登录
2017-4-21
发表于 2016-4-20 10:42:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 BobbyKim 于 2016-4-20 10:44 编辑

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

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

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


  思路:用手机移动来控制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>();

  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<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 .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> ().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、最后遇到的,我无法解决的问题

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

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

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

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



20160311114307927.jpg


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


评分

参与人数 1鲜花 +5 收起 理由
huo3ge + 5 赞一个!

查看全部评分

本帖被以下淘专辑推荐:


回复

使用道具 举报

7日久生情
1657/5000
排名
679
昨日变化

6

主题

255

帖子

1657

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
880
好友
9
蛮牛币
2122
威望
10
注册时间
2013-7-15
在线时间
426 小时
最后登录
2017-4-21
发表于 2016-4-21 11:35:18 | 显示全部楼层
已经很厉害了

回复

使用道具 举报

2初来乍到
116/150
排名
14054
昨日变化
5

2

主题

34

帖子

116

积分

Rank: 2Rank: 2

UID
32945
好友
0
蛮牛币
78
威望
0
注册时间
2014-7-7
在线时间
51 小时
最后登录
2017-3-29
QQ
发表于 2016-10-11 17:08:23 | 显示全部楼层
阿凡达手动阀手动阀手动阀手动阀

回复 支持 反对

使用道具 举报

0

主题

5

帖子

8

积分

Rank: 1

UID
177673
好友
0
蛮牛币
23
威望
0
注册时间
2016-10-23
在线时间
4 小时
最后登录
2016-11-12
发表于 2016-10-29 21:55:04 | 显示全部楼层
已经很厉害了、、、

回复 支持 反对

使用道具 举报

0

主题

4

帖子

10

积分

Rank: 1

UID
180261
好友
0
蛮牛币
24
威望
0
注册时间
2016-11-3
在线时间
7 小时
最后登录
2017-3-27
发表于 2016-11-3 17:20:26 | 显示全部楼层
楼主牛逼!请问实现这个效果有用到第三方的AR SDK吗?

回复 支持 反对

使用道具 举报

3偶尔光临
187/300
排名
11824
昨日变化
5

0

主题

47

帖子

187

积分

Rank: 3Rank: 3Rank: 3

UID
114045
好友
0
蛮牛币
129
威望
0
注册时间
2015-7-17
在线时间
96 小时
最后登录
2017-4-17
QQ
发表于 2016-12-27 10:44:52 | 显示全部楼层
有源码下载吗

回复

使用道具 举报

3偶尔光临
235/300
排名
7904
昨日变化
4

7

主题

38

帖子

235

积分

Rank: 3Rank: 3Rank: 3

UID
163083
好友
1
蛮牛币
108
威望
0
注册时间
2016-8-19
在线时间
94 小时
最后登录
2017-4-24
发表于 2017-2-25 14:10:23 | 显示全部楼层
错误        1        “System.Array”不包含“isFrontFacing”的定义,并且找不到可接受类型为“System.Array”的第一个参数的扩展方法“isFrontFacing”(是否缺少 using 指令或程序集引用?)        C:\Users\admin\Desktop\Eartquakelivingroom02\Assets\Plane.cs        19        40        Assembly-CSharp
错误        2        “System.Array”不包含“name”的定义,并且找不到可接受类型为“System.Array”的第一个参数的扩展方法“name”(是否缺少 using 指令或程序集引用?)        C:\Users\admin\Desktop\Eartquakelivingroom02\Assets\Plane.cs        22        66        Assembly-CSharp

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1354/1500
排名
893
昨日变化

1

主题

72

帖子

1354

积分

Rank: 6Rank: 6Rank: 6

UID
67101
好友
1
蛮牛币
2072
威望
0
注册时间
2015-1-9
在线时间
441 小时
最后登录
2017-4-24
QQ
发表于 2017-3-2 09:51:45 | 显示全部楼层
楼主很强大了,我研究了很长时间都没有做到楼主这个地步。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表