Unity 攝像機搭配陀螺儀的使用

項目起因:

前段時間自己在做的一個項目中需要實現一個類似AR的相機實現。舉例來說就是App中打開照相機,然后屏幕中顯示相機背景然后再顯示一個模型,但是模型的世界坐標是不會變化的,不會隨著手機的轉動而跟著轉動、

1.相機實現原理:

  • 獲取手機的姿態(陀螺儀)
  • 實例化3D模型且固定
  • 根據陀螺儀修改場景內相機的位置,姿態

2.ARCamera的結構:

ARCamera的結構
ARCamera的結構

;

3.代碼實現:

ARCamera上的Cs腳本:

using UnityEngine;
using System.Collections;
public class CameraTrack : MonoBehaviour {
    //PC上模擬陀螺儀的輸入值
    public Vector3 debugGro = new Vector3(0f,0f,0f);
    public bool isDebug = false;
    //用來定位的模型
    public GameObject model;
    // Use this for initialization
    void Start () {
        //陀螺儀的設置
        Input.gyro.enabled = true;
        Input.compensateSensors = true;
        Input.gyro.updateInterval = 0.01f;
        }
        // Update is called once per frame
        void Update () {
            //根據陀螺儀返回的數據設置Camera的姿態。
            gameObject.transform.localRotation = (isDebug ? Quaternion.Euler (debugGro) : Input.gyro.attitude)* new Quaternion(0,0,1,0);
        //如果第一次啟動就對定位的模型進行賦值,設置其在屏幕的中央。(此處為我的項目需要用到的,可以忽略。)
        if(model.GetComponent().enabled == false){
            StartCoroutine (ScriptTrue ());
        }
    
    }
    IEnumerator ScriptTrue(){
        yield return new WaitForSeconds (0.3f);
        model.GetComponent ().enabled = true;
    }
}

Quad上的Cs腳本。


using UnityEngine;
using System.Collections;
public class CameraSetting : MonoBehaviour {
    public int Camertype;
    public int CamerFPS;
    public int CamerWidth;
    public int CamerHeight;
    private WebCamTexture t;
    private WebCamDevice[] mWebCamDevices;
    private bool isDebug;
    private bool isNeedSetCamera = true;
    // Use this for initialization
    void Start () {
        isDebug = gameObject.GetComponentInParent().isDebug;
        StartCoroutine (initWebCamera());
    }
    IEnumerator initWebCamera(){
        //權限判斷,之前這里的寫法沒注意導致第一次進入會黑屏(iOS)
        yield return Application.RequestUserAuthorization (UserAuthorization.WebCam);
        if (Application.HasUserAuthorization(UserAuthorization.WebCam)){
            //拿手機上的相機
            mWebCamDevices = WebCamTexture.devices;
            //CameraType 0后置。根據不同進行判斷
            string name = mWebCamDevices [Camertype].name;
            t = new WebCamTexture (name);
            //這里設置的分辨率都不是最終的,最終獲取到的分辨率是根據相機自己的參數來的,它會給你匹配一個最接近你設置的。
            t.requestedFPS = CamerFPS;
            t.requestedHeight = CamerHeight;
            t.requestedWidth = CamerWidth;
            //設置Quad的貼圖為相機拍攝到的。
            GetComponent ().material.mainTexture = t;
            t.Play ();
            //下面一句必須放在Play后面,否則t.width等獲得不到數據。
            //旋轉畫布到正的位置,這里要特別注意,有些時候會出現畫面橫過來或者倒了。
            gameObject.transform.localRotation = gameObject.transform.localRotation 
                * Quaternion.AngleAxis(t.videoRotationAngle,Vector3.forward);
        }
    }
    // Update is called once per frame
    void Update () {
        //設置Quad畫布的大小,如果寫在play后面會導致部分時候獲取的數據為1。應該是相機還沒打開真正打開就開始獲取了,所以數據有誤,所以放在了這里。
        if (isNeedSetCamera && t!=null && t.width >200 && t.height >200){
            //判斷是否翻轉。
            gameObject.transform.localScale = new Vector3(t.width*-1, t.height*(t.videoVerticallyMirrored?1:-1), 1f);
            //計算場景內相機的視域(重要)
            gameObject.GetComponentInParent ().fieldOfView = 
                Mathf.Atan(t.height / 2f / gameObject.transform.localPosition.z) * Mathf.Rad2Deg * 2-1;
            isNeedSetCamera = (t.width <200 && t.height <200);
        }
    }
    public void StopWebCamera(){
        if (t != null) {
            t.Stop ();
        }
    }
    public void PauseWebCamera(){
        if (t != null && t.isPlaying) {
            t.Pause ();
        }
    }
    public void StartWebCamera(){
        if (t != null) {
            t.Play ();
            isNeedSetCamera = true;
        }
    }
}

4.關鍵語句(部分偽代碼):

設置相機為陀螺儀姿態:

Input.gyro.attitude * new Quaternion(0,0,1,0);

畫布旋轉到攝像機的正的位置:

localRotation = localRotation * Quaternion.AngleAxis(t.videoRotationAngle,Vector3.forward);

判斷是否翻轉:

localScale = new Vector3(t.width*-1,t.height*(t.videoVerticallyMirrored?1:-1), 1f);

計算視域

Camera.fieldOfView = Mathf.Atan(t.height / 2f / Vector3.Distance(Camera.position,Quad.position)) * Mathf.Rad2Deg * 2;

4.總結:

代碼都在上面,有了注釋就不在進行分析了。相機的使用這塊爬了不少的坑,主要就是在旋轉上,對其旋轉之類的坐標不是很了解,所以花了挺多時間。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容