欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于Unity3D的相机功能的实现(一)——VR相机

程序员文章站 2022-04-18 19:55:39
...
Unity自带陀螺仪功能,今天就利用陀螺仪实现一个VR相机功能。步骤如下:
  1. 打开Unity,创建一个新的C#脚本GyroController.cs,并挂在MainCamera游戏对象上,代码如下:
    using UnityEngine;
    using System.Collections;
    
    public class GyroController : MonoBehaviour
    {
        // Fields
        private readonly Quaternion baseIdentity = Quaternion.Euler(90f, 0f, 0f);
        private Quaternion baseOrientation = Quaternion.Euler(90f, 0f, 0f);
        private Quaternion baseOrientationRotationFix = Quaternion.identity;
        private Quaternion calibration = Quaternion.identity;
        private Quaternion cameraBase = Quaternion.identity;
        private bool debug = true;
        public static bool gyroAvaiable;
        private bool gyroEnabled = true;
        private Quaternion gyroInitialRotation;
        public static bool gyroOff;
        private Quaternion initialRotation;
        private readonly Quaternion landscapeLeft = Quaternion.Euler(0f, 0f, -90f);
        private readonly Quaternion landscapeRight = Quaternion.Euler(0f, 0f, 90f);
        private const float lowPassFilterFactor = 0.1f;
        private Quaternion offsetRotation;
        private Quaternion referanceRotation = Quaternion.identity;
        private readonly Quaternion upsideDown = Quaternion.Euler(0f, 0f, 180f);
    
        // Methods
        private void AttachGyro()
        {
            this.gyroEnabled = true;
            this.ResetBaseOrientation();
            this.UpdateCalibration(true);
            this.UpdateCameraBaseRotation(true);
            this.RecalculateReferenceRotation();
        }
    
        private void Awake()
        {
            gyroAvaiable = SystemInfo.supportsGyroscope;
        }
    
        private static Quaternion ConvertRotation(Quaternion q)
        {
            return new Quaternion(q.x, q.y, -q.z, -q.w);
        }
    
        private void DetachGyro()
        {
            this.gyroEnabled = false;
        }
    
        private Quaternion GetRotFix()
        {
            return Quaternion.identity;
        }
    
        private void RecalculateReferenceRotation()
        {
            this.referanceRotation = Quaternion.Inverse(this.baseOrientation) * Quaternion.Inverse(this.calibration);
        }
    
        private void ResetBaseOrientation()
        {
            this.baseOrientationRotationFix = this.GetRotFix();
            this.baseOrientation = this.baseOrientationRotationFix * this.baseIdentity;
        }
    
        protected void Start()
        {
    
                Input.gyro.enabled = true;
                base.enabled = true;
            this.AttachGyro();
            this.initialRotation = base.transform.localRotation;
            this.gyroInitialRotation = Input.gyro.attitude;
        }
    
        private void Update()
        {
            gyroOff = PlayerPrefs.GetInt("gyro-off") == 1;
            if (this.gyroEnabled )
            {
                base.transform.localRotation = Quaternion.Slerp(base.transform.localRotation, this.cameraBase * (ConvertRotation(this.referanceRotation * Input.gyro.attitude) * this.GetRotFix()), 0.5f);//0.1f
            }
        }
    
        private void UpdateCalibration(bool onlyHorizontal)
        {
            if (onlyHorizontal)
            {
                Vector3 toDirection = (Vector3) (Input.gyro.attitude * -Vector3.forward);
                toDirection.z = 0f;
                if (toDirection == Vector3.zero)
                {
                    this.calibration = Quaternion.identity;
                }
                else
                {
                    this.calibration = Quaternion.FromToRotation((Vector3) (this.baseOrientationRotationFix * Vector3.up), toDirection);
                }
            }
            else
            {
                this.calibration = Input.gyro.attitude;
            }
        }
    
        private void UpdateCameraBaseRotation(bool onlyHorizontal)
        {
            if (onlyHorizontal)
            {
                Vector3 forward = base.transform.forward;
                forward.y = 0f;
                if (forward == Vector3.zero)
                {
                    this.cameraBase = Quaternion.identity;
                }
                else
                {
                    this.cameraBase = Quaternion.FromToRotation(Vector3.forward, forward);
                }
            }
            else
            {
                this.cameraBase = base.transform.rotation;
            }
        }
    }
  2. 在相机MainCamera下创建一个新的Camera相机,并改变两个相机的Viewport Rect属性,以将屏幕均分,如图:基于Unity3D的相机功能的实现(一)——VR相机基于Unity3D的相机功能的实现(一)——VR相机
  3. 在场景中创建一个Cube,效果如图:基于Unity3D的相机功能的实现(一)——VR相机
  4. 保存场景,打包成apk,安装到手机即可。基于Unity3D的相机功能的实现(一)——VR相机基于Unity3D的相机功能的实现(一)——VR相机基于Unity3D的相机功能的实现(一)——VR相机