博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UniMelb Comp30022 IT Project (Capstone) - 2.Vuforia in Unity
阅读量:5095 次
发布时间:2019-06-13

本文共 7989 字,大约阅读时间需要 26 分钟。

2 Vuforia in Unity

Tutorial: https://www.youtube.com/watch?v=X6djed8e4n0&t=213s

Preparation: 

Download "Vuforia for Unity" from https://developer.vuforia.com/downloads/sdk?d=windows-30-16-4815&retU

import Vuforia into Unity by dragging "vuforia-unity-xxx.unitypackage" into Unity project window

AR Camera:

Assets > Vuforia > Prefabs > drag ARCamera into the scene & save as ufoScene

Add a license key in https://developer.vuforia.com/targetmanager/licenseManager/licenseListing

Select ARCamera object and Open Vuforia Configuration in the inspector window, and put in app license key

save and run, the camera is on~

Import Game Asset: http://wirebeings.com/markerless-gps-ar.html

extract it and drag it into unity

drag a flying disk into the scene; scale to 0.1; position to (4.3, 29.7, 200)

now the ufo is fixed on the center of the screen

For the purpose of fixing the position of the ufo at the geolocation in reality:

Change World Center Mode to "Device Tracking"

Open Vuforia Configuration and tick Enable device pose track

UI Text: to show the distance

add UI > Text called distance, and adjust the position and change the text color and content, change Horizontal Overflow to overflow

add a UI Image as the background for the UI Text, adjust the position and change the color and transparent

add a tag called distanceText and set the tag of Text distance to it

Script:

add a script called AugmentedScript to Flying Disk object

ref: http://wirebeings.com/markerless-gps-ar.html

using UnityEngine;using System.Collections;using UnityEngine.UI;public class AugmentedScript : MonoBehaviour{  private float originalLatitude;  private float originalLongitude;  private float currentLongitude;  private float currentLatitude;  private GameObject distanceTextObject;  private double distance;  private bool setOriginalValues = true;  private Vector3 targetPosition;  private Vector3 originalPosition;  private float speed = .1f;  IEnumerator GetCoordinates()  {    // update/get device's gps coordinates  }  public void Calc(float lat1, float lon1, float lat2, float lon2)  {
// calculates distance between two sets of coordinates, taking into account the curvature of the earth } void Start(){ // initialization } void Update(){ // update each frame }}

Script Comments:

void start(): initialization

void Start(){    // get the reference to UIText distance to get the user gps coordinates    distanceTextObject = GameObject.FindGameObjectWithTag ("distanceText");    // keep getting the gps coordinates from the phone    StartCoroutine ("GetCoordinates");    // initialize target and original position, transform refers to the flying disk    targetPosition = transform.position;    originalPosition = transform.position;}

 

void update(): update each frame

void Update(){    // linearly interpolate from current position to target position    transform.position = Vector3.Lerp(transform.position, targetPosition, speed);    // rotate by 1 degree about the y axis every frame    transform.eulerAngles += new Vector3 (0, 1f, 0);}
Vector3.Lerp(): https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html
public static Vector3 Lerp(Vector3 a,
Vector3 b, float t)
Linearly interpolates between the vectors a and b by the interpolant t (t = [0,1])
When 
t
 = 0 returns a. When t = 1 returns b. When t = 0.5 returns the point midway between a and b.

IEnumerator GetCoordinates(): update/get device's gps coordinates

IEnumerator GetCoordinates(){    // while true so this function keeps running once started.    while (true) {        // code from LocationService.Start documentation sample         // https://docs.unity3d.com/ScriptReference/LocationService.Start.html                // check if user has location service enabled        if (!Input.location.isEnabledByUser)            yield break;        // Start service before querying location        Input.location.Start (1f, 0.1f);        // Wait until service initializes        int maxWait = 20;        while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) {            yield return new WaitForSeconds (1);            maxWait--;        }        // Service didn't initialize in 20 seconds        if (maxWait < 1) {            print ("Timed out");            yield break;        }        // Connection has failed        if (Input.location.status == LocationServiceStatus.Failed) {            print ("Unable to determine device location");            yield break;        } else {            // start doing the device's coordinates processing                        // Access granted and location value could be retrieved            print ("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);            // if original value has not yet been set, then save player's coordinates when app starts            if (setOriginalValues) {                // "private bool setOriginalValues = true;" at the start                 originalLatitude = Input.location.lastData.latitude;                originalLongitude = Input.location.lastData.longitude;                setOriginalValues = false;            }            //overwrite current lat and lon everytime            currentLatitude = Input.location.lastData.latitude;            currentLongitude = Input.location.lastData.longitude;            //calculate the distance between where the player was when the app started and where they are now.            Calc (originalLatitude, originalLongitude, currentLatitude, currentLongitude);        }        Input.location.Stop();    }}

 

Input.location.Start(): https://docs.unity3d.com/ScriptReference/LocationService.Start.html

public void Calc(float lat1, float lon1, float lat2, float lon2): calculates distance between two sets of coordinates, taking into account the curvature of the earth

 

public void Calc(float lat1, float lon1, float lat2, float lon2){    var R = 6378.137; // Radius of earth in KM    var dLat = lat2 * Mathf.PI / 180 - lat1 * Mathf.PI / 180;    var dLon = lon2 * Mathf.PI / 180 - lon1 * Mathf.PI / 180;    float a = Mathf.Sin(dLat / 2) * Mathf.Sin(dLat / 2) +             Mathf.Cos(lat1 * Mathf.PI / 180) * Mathf.Cos(lat2 * Mathf.PI / 180) * Mathf.Sin(dLon / 2) * Mathf.Sin(dLon / 2);    var c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1 - a));    distance = R * c;    distance = distance * 1000f; // meters    //set the distance text on the canvas    distanceTextObject.GetComponent
().text = "Distance: " + distance; //convert distance from double to float float distanceFloat = (float)distance; //set the target position of the ufo, this is where we lerp to in the update function targetPosition = originalPosition - new Vector3 (0, 0, distanceFloat * 12); //distance was multiplied by 12 so I didn't have to walk that far to get the UFO to show up closer}

 

 

 

 

 

 

Build:

switch platform in build settings to Android

in player settings >

Identification > packageName: com.Company.ProductName

Build

Install:

go to .../Android/sdk/platform-tools

confirm your mobile device by ./adb devices

install the signed .apk by ./adb install apk_dir

and it works!

Oh...not really. The geo-location can not be access since there is no permission for the app to access gps service

if (!Input.location.isEnabledByUser) yield break;

http://answers.unity3d.com/questions/38222/android-plugin-and-permissions.html

--> set permissions in manifest.xml

Assets > Plugins > Android > AndroidManifest.xml

add <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

https://docs.unity3d.com/Manual/android-manifest.html;

https://developer.android.com/reference/android/Manifest.permission.html

And then I figure out the solution showed above is not a solution.

what actually happened in my device is the "Time Out", rather than "isEnabledByUser"

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/FudgeBear/p/7493053.html

你可能感兴趣的文章
jQuery源码分析(2) - 为什么不用new jQuery而是用$()
查看>>
jQuery源码分析(3) - 判断传入对象是否为function或array
查看>>
[转]【EL表达式】11个内置对象(用的少) & EL执行表达式
查看>>
ArrayList对象声明& arrayList.size()
查看>>
并发编程 线程
查看>>
Mysql 解压安装
查看>>
Mysql
查看>>
前端html
查看>>
网络编程
查看>>
初入社会的年轻人如何选择行业?
查看>>
《University Calculus》-chape10-向量和空间几何学-叉积
查看>>
统计学中相关数学符号、希腊字母的标准读法
查看>>
Win10正式企业版激活方法
查看>>
Cglib及其基本使用
查看>>
PHP 文件扫描器
查看>>
用 Java 实现的 Rc4 加密算法
查看>>
7-1 树的同构 (25 分)
查看>>
史上前端面试最全知识点
查看>>
构造器
查看>>
Java中toArray的用法探究(java数组与list转换)
查看>>