【Unity3D】AR应用中,关于东南西北方位的判断。
这篇文章的应用场景是这样子的:
首先我们要做的是一个带有LBS定位服务(比如高德地图、百度地图等)AR功能,在这个场景中,会有一些地图上的”点“(如派出所、学校)是我们需要显示在我们的AR镜头上的,如下图:

图片摘自wuyt2008的博客:《unity3d 尝试 基于地理定位的 增强现实》
本文要解决的问题就是,如何判断这些Point的东南西北,即坐标。
博主采用的开发环境是
- Unity3D: 5.3.5;
- EazyAR: SKD v1.3.0;
- GyroDroid :这个Unity3D 的传感器插件包上网搜一下就有了。
要应用本博客的内容之前,必须先看过wuyt2008的博客《unity3d 尝试 基于地理定位的 增强现实》。
开坑:
实际上我们要实现功能的原理就是根据定位返回的自身(Location)坐标(XL,ZL),跟我们需要标注显示出来的Marker的坐标(XM,ZM)进行坐标系的运算,很简单,
X∆=XL-XM,
Z∆=ZL-ZM,
然后我们再把我们的主摄像机的Position的x、z轴(Y是控制高的,与物体平面定位没有关系)设置为(0,0),这样呢,Marker在Unity中得坐标,就是(X∆,Z∆),并且经过我的测试,Unity中在使用ARCamera的情况下,+X轴指的方向是东90°,+Z轴指的方向是北90°。我们根本不需要做任何其他判断,只需要根据这个特性,再根据经纬度的数据特性,如果X∆的值为负,则表示Marker位于东边(相对自身),如果Z∆的值为负,则表示Marker位于北边(相对自身),所以只需要按照(-X∆,-Z∆)设置Marker的(X,Z)坐标,即可准确的安放Marker的位置。
首先,我们使用EazyAR SDK 中提供的AR摄像机,为什么说它是AR摄像机呢,因为它本身已经根据AR应用的特性,进行了一些优化,还有添加了一些C# Script,所以直接拿来用,你会发现比你自己写一大堆乱七八糟的代码好多了。然后呢,再将GyroDroid插件包中的“MinimalSensorCamera”脚本,绑定到摄像机上,让AR摄像机镜头随着手机的旋转而旋转。
然后就是最重要的一个环节,这里要结合wuyt2008博主的博客中得代码来介绍,我把代码贴一下,并且我自己加了一些注释,助于观看:
1 using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI; public class ARMange : MonoBehaviour { public List<PlaceInfo> places = new List<PlaceInfo>();//Marker的集合(Marker是什么,请学习一下高德地图api的应用,简单的说,就是你想要标记在地图上的点,比如一些餐厅或景点之类,甚至可以是自定义的点)
public GameObject perfab;
public PlaceInfo location = new PlaceInfo ();//根据高德API定位后传递过来的自身坐标信息 public void ShowPlaces(){
ClearPlace (); for (int i = ; i < places.Count; i++) { GameObject newPlace = Instantiate<GameObject> (perfab);
newPlace.transform.parent = this.transform; double posZ = places [i].Latitude - location.Latitude;//计算相对距离,z轴(Unity中的坐标系)
double posX = places [i].Longitude - location.Longitude;//计算相对距离,x轴(Unity中的坐标系) float z = ;
float x = ;
float y = ; if (posZ > ) {
z = 500f;
} else {
z = -500f;
} if (posX > ) {
x = 500f;
} else {
x = -500f;
} z = z + (float)(posZ * );
x = x + (float)(posX * );
y = y + i * ; newPlace.transform.position = new Vector3 (x, y, z);//设置Marker
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 = ; i < oldPlaces.Length; i++) {
Destroy (oldPlaces [i].gameObject);
}
}
}
然后我们把Unity3D中,ARCamera(AR摄像机)的Position,设置为(0,0,0)这么做呢,是方便等会儿设定Marker的坐标,只有相机坐标设置为这样子,X∆和Z∆的值才是Marker的直接坐标,否则还得进行一些运算。不过这里值得注意的是,坐标系的设定,应该在CameraDevice对象上,否则是无效的。
然后我们修改上述的代码,修改起来,并不会太难,只需要修改第43行,改成:
20 double posZ = places [i].Latitude - location.Latitude;//计算相对距离,z轴(Unity中的坐标系)
double posX = places [i].Longitude - location.Longitude;//计算相对距离,x轴(Unity中的坐标系)
newPlace.transform.position = new Vector3 (-x, y, -z);//设置Marker
这样就完事儿了。。。wuyt2008的博客《unity3d 尝试 基于地理定位的 增强现实》最后所提及的偏移问题,貌似没有这种情况,可能是跟EazyAR提供的ARCamera有关,以及镜头自动会有东南西北的方向感。最后感谢wuyt2008,最近在做AR的项目CityHunter,一直在研究如何将高德定位整合进Unity3D来,虽然应用方面与其所描述的不太相干(实际上我要运用的是高德API的电子围栏的功能),但是在操作中可举一反三,果断是学习到了。
【Unity3D】AR应用中,关于东南西北方位的判断。的更多相关文章
- unity3D AR涂涂乐制作浅谈
unity3D AR涂涂乐制作浅谈 AR为现在是虚拟现实较为火爆的一个技术,其中有个比较炫酷的就是AR涂涂乐的玩法,这个技术可以把扫描到的图片上的纹理 粘贴到模型上实现为模型上色的功能,但是我们需要怎 ...
- TDD在Unity3D游戏项目开发中的实践
0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...
- Thinking in Unity3D:渲染管线中的Rendering Path
关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的 ...
- C# if中连续几个条件判断
C# if中连续几个条件判断 1.if (条件表达式1 && 条件表达式2) 当条件表达式1为true时 using System; using System.Collections. ...
- java中字符串的非空判断
问题如下:在java 中 字符串为null 如何判断String str;if(str==null) ??str.equal("null") ?? 答:我觉得应该搞清楚字符串对象和 ...
- [改善Java代码]在equals中使用getClass进行类型判断
建议47: 在equals中使用getClass进行类型判断 本节我们继续讨论覆写equals的问题.这次我们编写一个员工Employee类继承Person类,这很正常,员工也是人嘛,而且在JEE中J ...
- 使用反射+策略模式代替项目中大量的switch case判断
我这里的业务场景是根据消息类型将离线消息存入mongoDB不同的collection中.其中就涉及到大量的分支判断,为了增强代码的可读性和可维护性,对之前的代码进行了重构. 先对比一下使用反射+策略模 ...
- jquery中关于对象类型的判断原理
class2type[ core_toString.call(obj) ] jquery中关于对象类型的判断原理 jquery源码中关于类型判断的工具函数为type,调用方法为$.type()或者jQ ...
- MYSQL中可以实现类似IF判断的方法
MYSQL中可以实现类似IF判断的方法 新建一张客户表,如下:sex:1-男,2-女,3-未知:level是客户的级别:1-超级VIP客户,2-VIP客户,3-普通客户 方式一:case函数:流程控制 ...
随机推荐
- CentOS 6编译安装lamp,并分别安装event模块方式和FPM方式的PHP
任务目标: 编译安装LAMP 要求(1) 安装一个模块化的PHP 要求(2) 安装一个FPM的PHP 注意PHP需要最后一个安装,因为需要前两者的支持. 所以这里的安装次序为 1.httpd 2.Ma ...
- jQuery中多个元素的Hover事件
1.需求简介 jQuery的hover事件只是针对单个HTML元素,例如: $('#login').hover(fun2, fun2); 当鼠标进入#login元素时调用fun1函数,离开时则调用fu ...
- 浅谈iptables防SYN Flood攻击和CC攻击
------------------------本文为自己实践所总结,概念性的东西不全,这里粗劣提下而已,网上很多,本文主要说下目前较流行的syn洪水攻击和cc攻击------------------ ...
- MongoDB学习笔记~MongoDBRepository仓储的实现
回到目录 仓储大叔,只要是持久化的东西,都要把它和仓储撤上关系,为啥,为的是开发人员在使用时统一,高可用及方便在各种方式之间实现动态的切换,如ef与redis和mongoDB的切换,你完成可以通过IR ...
- 写了一个常规性生成merge 的小脚本
现在使用数据库来写存储过程,动不动参数就会用到xml ,当然罗,优势也很明显,参数相对固定,而且灵活,如果要修改或者什么的,中间接口层也不需要做变化,只需要修改封装的存储过程以及程序传参就ok了. 随 ...
- Linux Process VS Thread VS LWP
Process program program==code+data; 一个进程可以对应多个程序,一个程序也可以变成多个进程.程序可以作为一种软件资源长期保存,以文件的形式存放在硬盘 process: ...
- 3-4 linux 用户及权限管理
1. 安全上下文(secure context) 取决于资源权限和进程权限 分为三种:r:读,w:写,x:执行 每一类用户都有三个权限 文件: r:可读,可以使用类似cat等命令来查看文件内容 w:可 ...
- java笔记
ANT概述:http://www.blogjava.net/amigoxie/archive/2007/11/09/159413.html http://baitai.iteye.com/blog/7 ...
- 数据库SQL基本操作
1.查询表结构 desc 表名 2.显示当前连接用户 show user 3.查看系统拥有哪些用户 select * from all_users; 4.查询当前用户下所有对象 select * fr ...
- POJ 1325 Machine Schedule——S.B.S.
Machine Schedule Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13731 Accepted: 5873 ...
