文档章节

Unity 摄像机搭配陀螺仪的使用

Lohanry
 Lohanry
发布于 2016/12/21 00:30
字数 846
阅读 1060
收藏 2

项目起因:

前段时间自己在做的一个项目中需要实现一个类似AR的相机实现。举例来说就是App中打开照相机,然后屏幕中显示相机背景然后再显示一个模型,但是模型的世界坐标是不会变化的,不会随着手机的转动而跟着转动、

1.相机实现原理:

  • 获取手机的姿态(陀螺仪)
  • 实例化3D模型且固定
  • 根据陀螺仪修改场景内相机的位置,姿态

2.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<ModelPos>().enabled == false){
            StartCoroutine (ScriptTrue ());
        }
    
    }
    IEnumerator ScriptTrue(){
        yield return new WaitForSeconds (0.3f);
        model.GetComponent<ModelPos> ().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<CameraTrack>().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<Renderer> ().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 <Camera>().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.总结:

代码都在上面,有了注释就不在进行分析了。相机的使用这块爬了不少的坑,主要就是在旋转上,对其旋转之类的坐标不是很了解,所以花了挺多时间。

© 著作权归作者所有

共有 人打赏支持
Lohanry

Lohanry

粉丝 6
博文 10
码字总数 11765
作品 1
宁波
程序员
私信 提问
Unity Shader中各种空间及变换方法

前几天尝试写一个传送门的shader,发现自己对坐标之间的变换掌握的不够熟练,趁着这阵子想整理shader相关的知识点,先把各种空间及之间转换整理一下。 1 模型空间-世界空间-观察空间-裁剪空间...

爽歪歪ES
2018/07/18
0
0
【Unity3D技术文档翻译】第3.5篇 阴影概述

上一章:【Unity3D技术文档翻译】第3.4.4篇 Cookies 本章原文所在章节:【Unity Manual】→【Graphics】→【Graphics Overview】→【Lighting】→【Light sources】→【Shadows】 阴影概述 ...

何三思
2018/07/09
0
0
Mogoson/CubemapRenderer

CubemapRenderer English Manual 概述 Unity Cubemap渲染器。 需求 有时,发现一些Unity资源包中的场景的环境效果不错,希望将其渲染成Cubemap供天空盒使用。 Unity场景中需要制作一些反射效...

Mogoson
2018/08/22
0
0
Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收(九)

Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6926746 ...

彭博
2012/03/09
770
0
Razer 发布 199 美金的开源虚拟现实头戴设备

Razer 是一个游戏电脑和外围设备的制造厂商,刚刚宣布进军虚拟现实空间,在 CES 上推出一款标价 199 美金的 OSVR Hacker Dev Kit 头戴设备。该设备将在今年 6 月份推出。 同时 Razer 还发布一...

oschina
2015/01/07
2.1K
18

没有更多内容

加载失败,请刷新页面

加载更多

rabbitmq安装教程

RabbitMQ有Windows与Linux版本的,这里先写Windows版本的安装。 以前安装软件总是在百度上找某某安装教程,结果能按照教程安装好的软件真的不多。想起先前以为大牛说的一句话,去官网按照官网...

em_aaron
今天
6
0
Android 贝塞尔曲线实践——波浪式运动

一、波浪效果如下 贝塞尔曲线自定义波浪效果的案例很多,同样方法也很简单,大多数和本案例一样使用二次贝塞尔曲线实现,同样还有一种是PathMeasure的方式,这里我们后续补充,先来看贝塞尔曲...

IamOkay
今天
3
0
Nmap之防火墙/IDS逃逸

选项 解释 -f 报文分段 --mtu 指定偏移大小 -D IP欺骗 -sI 原地址欺骗 --source-port 源端口欺骗 --data-length 指定发包长度 --randomize-hosts 目标主机随机排序 --spoof-mac Mac地址欺骗 ...

Frost729
今天
2
0
带你搭一个SpringBoot+SpringData JPA的环境

不知道大家对SpringBoot和Spring Data JPA了解多少,如果你已经学过Spring和Hibernate的话,那么SpringBoot和SpringData JPA可以分分钟上手的。 其实我在学完SpringBoot和SpringData JPA了之...

java菜分享
今天
7
0
Chocolatey 在Window搭建一个开发环境

在看了(利用 Chocolatey 快速在 Windows 下搭建一个开发环境)后,准备从零开始 一、准备工作 1、用管理员权限启动:powershell,执行错误请参考(PowerShell因为在此系统中禁止执行脚本的解...

近在咫尺远在天涯
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部