• UniMelb Comp30022 IT Project (Capstone)


    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> ().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"

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    Mac 卸载MySql的方法
    关于mysql的wait_timeout参数 设置不生效的问题
    linux下利用nohup后台运行jar文件包程序
    MySql创建视图
    spring mvc获取header
    Spring Data Jpa 查询返回自定义对象
    Caused by: org.xml.sax.SAXParseException: The reference to entity "characterEncoding" must end with the ';' delimiter.
    eclipse Reference 功能之——项目之间的引用
    Mac 在启动eclipse时 Failed to load JavaHL Library解决方法
    MySQL Workbench update语句错误Error Code: 1175.
  • 原文地址:https://www.cnblogs.com/FudgeBear/p/7493053.html
Copyright © 2020-2023  润新知