1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright 2015-2017 Pico Technology Co., Ltd. All Rights 3 // File: Pvr_UnitySDKHeadTrack 4 // Author: AiLi.Shang 5 // Date: 2017/01/13 6 // Discription:Main tracking,manage the rotation of cameras.Be fully careful of Code modification 7 /////////////////////////////////////////////////////////////////////////////// 8 using UnityEngine; 9 using System.Collections.Generic; 10 using System.Text.RegularExpressions; 11 using System; 12 13 public class Pvr_UnitySDKHeadTrack : MonoBehaviour //头部跟踪 14 { 15 16 public bool trackRotation = true; //跟踪旋转角度 17 18 public bool trackPosition = true; //跟踪位置信息 19 20 public Transform target;//定义目标组件位置 21 22 private bool updated = false;//设置更新状态 23 24 private Vector3 startPosition;//定义开始的位置,旋转角度,大小的开始位置信息 25 26 private Quaternion startQuaternion;//开始的四元数角度信息 27 private bool dataClock;//定义数据记录变量 28 29 public void Awake() 30 { 31 if (target == null) //判断有无目标物体,如果没有目标物体,这组件以父级组件为中心,否则以世界坐标为中心 32 { 33 startPosition = transform.localPosition; 34 startQuaternion = transform.localRotation; 35 } 36 else 37 { 38 startPosition = transform.position; 39 startQuaternion = transform.rotation; 40 } 41 //Pvr_UnitySDKAPI.Sensor.UPvr_InitPsensor(); 42 43 } 44 45 public Ray Gaze //定义凝视射线类 46 { 47 get 48 { 49 UpdateHead();//更新头部位置,返回射线信息 50 return new Ray(transform.position, transform.forward); 51 } 52 } 53 54 void Update() 55 { 56 updated = false; // OK to recompute head pose. 57 //# if!UNITY_EDITOR && UNITY_ANDROID 58 // if (Pvr_UnitySDKManager.SDK.posStatus == 1 || Pvr_UnitySDKAPI.Sensor.UPvr_GetPsensorState() == 1) 59 // { 60 // trackPosition = false; 61 // if (!dataClock) 62 // { 63 // Pvr_UnitySDKManager.SDK.resetBasePos = Pvr_UnitySDKManager.SDK.HeadPose.Position; 64 // dataClock = true; 65 // } 66 // } 67 // else 68 // { 69 // if (dataClock) 70 // { 71 // Pvr_UnitySDKAPI.Sensor.UPvr_OptionalResetSensor((int)Pvr_UnitySDKAPI.Sensorindex.Default, 0, 1); 72 // Pvr_ControllerManager.controllerlink.ResetHeadSensorForController(); 73 // Pvr_ControllerManager.controllerlink.ResetController(0); 74 // Pvr_ControllerManager.controllerlink.ResetController(1); 75 // } 76 // trackPosition = true; 77 // dataClock = false; 78 // } 79 //#endif 80 UpdateHead(); 81 } 82 83 private void UpdateHead()
//此函数分为两部分,主要判断头部跟踪是否有旋转变换和是否有目标一共四种情况,默认状态是有旋转变换 84 { 85 if (updated)//判断是否更新了数据,初始化时,设置Update为false,即没有更新数据 86 { 87 return; 88 } 89 updated = true;//设置Update为true,开始更新数据 90 if (Pvr_UnitySDKManager.SDK == null)//判断PvrSDK的管理文件是否为空,若为空,这不更新,退出当前程序 91 { 92 return; 93 } 94 if (trackRotation)//判断头部跟踪时是否有旋转变化,初始化时,设置trackRotation为true 95 { 96 var rot = Pvr_UnitySDKManager.SDK.HeadPose.Orientation;//把PvrSdk管理文件下的头部位置的方向赋值给rot变量 97 if (target == null)
//如果没有目标物体,则把Rot的信息赋值组件的本地位置,如果有目标物体,这将rot与目标物体的乘积赋值给组件的世界坐标 98 { 99 transform.localRotation = rot; 100 } 101 else 102 { 103 transform.rotation = rot * target.rotation; 104 } 105 } 106 107 else 108 { 109 var rot = Pvr_UnitySDKManager.SDK.HeadPose.Orientation; 110 if (target == null) 111 { 112 transform.localRotation = Quaternion.identity; 113 } 114 else 115 { 116 transform.rotation = rot * target.rotation; 117 } 118 } 119 if (trackPosition) 120 { 121 Vector3 pos = Pvr_UnitySDKManager.SDK.HeadPose.Position; 122 if (target == null) 123 { 124 transform.localPosition = pos; 125 } 126 else 127 { 128 transform.position = target.position + target.rotation * pos; 129 } 130 } 131 } 132 133 }
代码结构:
定义相关变量
定义射线函数
定义数据更新信息:是否有目标物体,是否有旋转信息,位置更新3个子部分
有无Target的区别是:如在监视面板中添加ObjectGame为Target时,可以理解为以该游戏对象为第一人称观察世界,也ObjectGame为中心
如果没有添加Target,则可理解为以第三人称观看世界,以SDK的组照相机为中心
Unity VR 常用的组件类:
Transform类
transform.localPosition是相对学父级对象的坐标位置,父级为坐标中心
transform.position世界坐标,以(0,0,0)为中心
Vector3类
Quaternion(四元数和旋转)类-旋转分为矩阵旋转;欧拉旋转和四元数旋转
小技巧
HideInInspector在监视窗口隐藏变量的边框