VR开发中陀螺仪数据转换
程序员文章站
2022-04-18 19:56:21
...
1、判断手机是否支持陀螺仪
SystemInfo.supportsGyroscope
2、获取陀螺仪数据并转换
Gyroscope gyro = Input.gyro;
gyro.enabled = true;
读取陀螺仪数据并转换到右手坐标系下
var att = Input.gyro.attitude * Quaternion.identity;
att = new Quaternion(att.x, att.y, -att.z, -att.w);
由于unity里边是左手坐标系,因此需要做偏转(先进行a旋转再进行b旋转等价于执行乘积ba代表的单一旋转因此四元数能用来连接多次旋转,这个矩阵乘法的效果一样,根据四元数乘法的定义这个旋转是以从右向左的顺序发生的**)
Quaternion curGyroRotation = Quaternion.Euler(90, 0, 0) * att;
3、但是实现开发过程中游戏内部的正方向是一定的,要让用户以不同的方向进入游戏都可以正常玩,就需要求出当前陀螺仪数据和游戏中初始方向的差值,当然差值x,y,z方向都有值,但为了用户方便,把x,z方向的偏差忽略,只计算y方向的偏差,如果算x,z,用户在使用过程中旋转角度会很累,脖子的偏转角度有限,哈哈。。。
curGyroRotation = Quaternion.Euler(0, curGyroRotation.eulerAngles.y, 0);
//trsRoler.eulerAngles 游戏开始时角色的角度
Quaternion standRotation = Quaternion.Euler(0, trsRoler.eulerAngles.y, 0);
Quaternion gyroRotationOff = Quaternion.Inverse(curGyroRotation) * standRotation;
为什么要用这个函数(Quaternion.Inverse),看下图
由于四元数相乘是角度的叠加,要求角度差,只能通过矩阵转置了。
求得角度差之后我们就可以拿来改变摄像机了
Quaternion realGyroRotation = Quaternion.Euler(90, gyroRotationOff .eulerAngles.y, 0) * att;
4、游戏刚开始时,不可能让玩家带着cardboard转圈去找startUI, 因此必须固定y和z,只让用户能够操控x,就头上下活动,注(场景中NGUI的3D摄像机UI)
Quaternion tmpRotation = GetGyroRotation();
Vector3 euler = tmpRotation.eulerAngles;
euler.y = 0;
euler.z = 0;
trsUICamera3D.eulerAngles = euler;
距离做完VR半年过去了,最近同事问,又给同事讲解了下,贴出自己的拙见供大家探讨!