Unity Gyro Camera ---- 传感器控制摄像头旋转 + 正北校准 (纯原生支持Android+IOS,无需安装ARKit,ARCore等插件)

news/2025/3/15 4:10:27/文章来源:https://www.cnblogs.com/starskyli/p/18344089

Unity Gyro Camera

传感器控制摄像头旋转 + 正北校准

纯原生支持Android+IOS,无需安装ARKit,ARCore等插件

这篇文章主要介绍如何利用手机原生的传感器,控制摄像头的旋转,最终可以实现AR或者VR的摄像头旋转控制

问题提出


 

  虽然,目前有一些用手机传感器控制虚拟摄像头旋转的方案,但是实际在一些应用中,需要手机的旋转和物理世界的是一样的。也就是说,如果手机朝着物理世界的正北方向,游戏里的场景也是朝着正北方向的。如果您不需要做正北的校准,那么可以忽略这篇文章,Unity官方文档就有实现方式。

目前情况


 

  虽然,目前网络上(无论国内还是国外)都有一些案例在Unity中利用传感器控制虚拟摄像头旋转的操作,但是总体来说存在以下的问题:

  1. 网上的方案都太旧了,适配Unity5或者IOS很早的版本
  2. 网上的方案层次不齐,有的方案写的代码太复杂了,最后化简下来都一样,但可能就看到一个复杂的方案,研究半天
  3. 目前的方案,在安卓下可以很好的解决问题(旋转和物理正北是一致的),但是在IOS的手机上却不成功,没有做正北的校准
  4. 网上又Unity Store中的方案,但是需要花钱购买(实际我购买后发现还是有问题的)
  5. 屏幕不同转向,结果不一样,有错误
  6. 或者需要安卓ARKit或者ARCore,ARFoundation等插件(如果要安装ARKit还需要申请摄像头访问权限,但实际上如果在VR的环境,完全不需要用到摄像头)

https://discussions.unity.com/t/how-can-i-make-the-camera-rotate-with-gyroscope-appropriately/220673

Unity gyroscope: Explained with code examples - VionixStudio

GitHub - Deankovitch/UnityGyroAccelCamera: Some way to make gyroscope and accelerometer work on all devices, in all Unity versions, using AHRS algoritm

Using gyroscope to control a camera? - Questions & Answers - Unity Discussions

[Sharing] Gyroscope Camera Script (iOS tested) - Unity Engine - Unity Discussions

Sensor Camera (Not AR): Gyroscope & Accelerometer | 镜头 | Unity Asset Store

GitHub - hbollon/GyroscopeControl: 🌀 Unity script used for smooth and customizable object rotation with gyroscope (initially configured to rotate x and z axis using x and y axis of gyro but can be easily edited). It include initial calibration with offset, rotation speed (Time.deltaTime * velocity), smoothing parameter editable in Unity inspector and debug overlay.

Quaternions applied to Sensor Fusion: gyro.attitude with compass - Questions & Answers - Unity Discussions

Match Unity camera with iPhone camera - Unity Engine - Unity Discussions

About attaching the unity camera to a gyro + magnetometer - Unity Engine - Unity Discussions

目标


 

    所以,我们要实现的目标是:

  1. 兼容安卓/IOS
  2. 有正北校准
  3. 无需安装多余插件
  4. 无需创建多余游戏物体,直接代码附加在要控制的组件(虚拟摄像头)
  5. 支持各种屏幕旋转方向

问题的产生


 

之所以,在安卓的环境下,不会有正北校准的问题,是因为Unity的接口: 

Input.gyro.attitude

本身已经融合了地磁的数据,所以无论手机在什么方向,都可以和物理的世界保持一致。但是IOS系统中,并没有做融合,需要手动操作。

虽然,我们可以通过:

Input.compass.trueHeading;
Input.compass.magneticHeading;

两个值,拿到当前物理正北的朝向,但是注意,这里返回的朝向是和屏幕方向密切相关的。它返回的值是,手机下方到上方的这条直线所在的方向,和物理世界的北极之间的角度。如果手机屏幕发生了旋转,最下方和最上方所在的轴并不是垂直与水平面的话,那么这个值是不准确的。

 例如上方的示意图,在手机完全水平(从下往上的轴在水平面的时候),这个时候的trueHeading或者magneticHeading的值,是和正北的夹角,但是当手机不是水平的时候(图例右侧),则这个角度(橙色的角)并不是真的正北朝向,而是蓝色角度,即手机从下往上的轴在水平面的投影与正北的夹角。

解决方案

综上所述,可以按照以下的代码完成最后的正北校准。

using UnityEngine;public class GyroWithCompass : MonoBehaviour
{private double _lastCompassUpdateTime = 0;private Quaternion _correction = Quaternion.identity;private Quaternion _targetCorrection = Quaternion.identity;void Start(){Input.location.Start();Input.gyro.enabled = true;Input.compass.enabled = true;}void Update(){//当前陀螺仪的值Quaternion q = Input.gyro.attitude;//转到unity坐标系Quaternion gyro = new(q.x, q.y, -q.z, -q.w);//因为在AR/VR环境,我们希望手机是竖起来的,所以需要x轴旋转90度Quaternion gyroOrientation = Quaternion.Euler(90, 0, 0) * gyro;
#if UNITY_ANDROIDtransform.rotation = gyroOrientation;
#else//下面需要做正北校准//如果地磁计有新数据的时候if (Input.compass.timestamp > _lastCompassUpdateTime){//存储刷新时间,以便判断是否有更新_lastCompassUpdateTime = Input.compass.timestamp;//根据水平仪(重力传感器,将手机从下网上的轴投影到水平面)Vector3 gravity = Input.gyro.gravity.normalized;Vector3 flatNorth = Input.compass.rawVector -Vector3.Dot(gravity, Input.compass.rawVector) * gravity;Quaternion compassOrientation = Quaternion.Inverse(Quaternion.LookRotation(flatNorth, -gravity));//转换到Unity坐标compassOrientation.z *= -1;compassOrientation.w *= -1;//计算最终正北校准需要的旋转四元数_targetCorrection = compassOrientation * Quaternion.Inverse(gyroOrientation);}//滤波_correction = Quaternion.Slerp(_correction,_targetCorrection,0.1f);//赋值transform.rotation = Quaternion.Euler(0, 180, 0) * _correction * gyroOrientation;
#endif}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/778356.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浮点数的表示及IEEE754标准

浮点数的表示浮点数的规格化IEEE754标准 移码IEEE754这里有一个需要特别注意的地方,IEEE754中,尾数个位上的1是隐含的IEEE 的阶码保留了全0和全1来表示特殊的状态,所以阶码最大值的真值为127,对应机器数为1111 1110,阶码最小值的真值为-126,对应的机器数为0000 0001

记一次STM32使用I2C PinRemap引脚重映射出现卡死现象

在移植WouoUI到STMF103C8 BluePill board时,发现会出现上电卡死在I2C检查函数(如下图)本人遇到的现象:在习惯使用的(SWI2C / HWI2C)@(PB8->SCL PB9->SDA)连接OLED的情况下,大多数情况使用江科大的SWI2C,一切正常。今天跑某开源基于u8g2库的UI框架 WouoUI(HWI2C)…

rancher2.5.9部署flink1.13.1集群问题求教

下面是我在rancher页面配置flink的yaml: apiVersion: batch/v1 kind: Job metadata: name: flink-jobmanager namespace: flink-resource spec: template: metadata: labels: app: flink component: jobmanager spec: restartPolicy: OnFailure containers: - name: jobmanage…

【报错提示】java.lang.RuntimeException: Cant create handler inside thread

​ 报错提示 遇到一个报错: java.lang.RuntimeException: Cant create handler inside thread Thread[OkHttp https://a.fxltsbl.com/...] that has not called Looper.prepare() 分析1. 这个报错提示是在一个没有调用 Looper.prepare() 的线程中尝试创建一个 Handler 对象。…

洛谷-P9830 题解

思路分析 分析样例:见红线,长宽各为 2,存在格点;黄线长 2 宽 3,没有格点。 考虑延长黄线使得长 4 宽 6,发现有格点。思考格点,如果长和宽都可以被分成 \(p\times l\) 的格式,则存在格点。那么,就能想出: 推论 1:对于 \((0 \ , \ 0)\) 和 \((x \ , \ y)\) 之间没有格…

kubernetes-存储卷与持久化详解

目录背景volume介绍emptyDirHostPathNFSconfigMapSecretPersistentVolume介绍PV回收策略PV访问策略基于nfs或nas创建pv创建hostpath类型的pvPV的状态PersistentVolumeClaim创建pvc与pv进行绑定使用pvc动态存储storageclass创建目录nfs添加授权目录创建yaml 背景 容器部署过程中…

如何通过视频剪辑软件修复原始视频声音小的问题 All In One

如何通过视频剪辑软件修复原始视频声音小的问题 All In One 视频后期处理 (剪映)如何通过视频剪辑软件修复原始视频声音小的问题 All In One视频后期处理 (剪映)demos视频声音太小了, 音量开到 100%,还是听不清,建议加个麦,或者后期处理视频的时候提高音量https://www.bilib…

kettle从入门到精通 第八十四课 ETL之kettle kettle中Get data from XML使用实战教程

场景:解析xml文件或者内容解析出其中某些字段。 本来想着这个步骤使用起来比较简单,就没有梳理成文,结果群里的小伙伴为了使用这个步骤折腾了一下午。故有了此文。 在开始学习之前我们一起来学习下xml命名空间的相关知识,为下文展开做基础铺垫。 1、xml命名空间XML 的命名空…

双边滤波

双边滤波(Bilateral Filtering)是一种非线性的图像处理方法,主要用于图像的平滑同时保持边缘清晰。与传统的低通滤波器(如均值滤波或高斯滤波)不同,双边滤波不仅考虑了空间上的邻近性,还考虑了像素值的相似性,这使得它能够在去除噪声的同时较好地保留图像的边界和细节。…

用项目详细讲讲vue3路由

1.【对路由的理解】 Vue Router 是 Vue.js 官方的路由管理器,它用于构建单页面应用(SPA),允许我们在不同的页面间进行导航,而无需刷新整个页面。 路由配置文件代码如下:import {createRouter,createWebHistory} from vue-router import Home from @/pages/Home.vue impo…

多态的概念,前提,注意事项以及访问成员的特点 day09

多态:某一个事物在不同状态下的多种状态举例:1、学生是人,老师是人,医生是人。2、汽态的水是水,固态的水是水,液态的水是水在java中要实现多态的话,需要有3个前提:1、必须要有继承关系2、要有方法的重写(思考可否不重写?)不是必须要重写的,重写可以体现子类的专属特…

[vue3] vue3初始化渲染流程

本文解析了 Vue3 组件初次渲染的流程,涵盖应用程序初始化、核心渲染步骤,以及 vnode 的创建和渲染,探讨了 Vue3 内部机制及其跨平台实现的关键细节。组件初次渲染流程 组件是对DOM树的抽象,组件的外观由template定义,模板在编译阶段会被转化为一个渲染函数,用于在运行时生…