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

陀螺仪控制相机运动

程序员文章站 2022-04-18 19:56:15
...

有时候我们需要通过陀螺仪控制相机的运动。这里有个demo供大家参考

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/*
 * Author:W
 * 陀螺仪控制相机
 */
public class GvrScopeCtrl : MonoBehaviour {
	public Transform cameraTran;
	public Button resetBtn;
	public Button switchBtn;

	private bool isGvrEnable = false;

	private  Vector3 CurEuler;




	/// <summary>
	/// 陀螺仪输入类型
	/// </summary>
	public enum EGyroInputType
	{
		RotateRate,
		RotateRateUniased,
		UserAcceleration,
	}

	/// <summary>
	/// 陀螺仪数据的更新频率 
	/// </summary>
	public int gvrRate = 30;

	/// <summary>
	/// 陀螺仪的输入参数,用以控制相机 
	/// </summary>
	public Vector3 gyroInput = Vector3.zero;

	/// <summary>
	/// 陀螺仪的输入参数,用以控制相机 
	/// </summary>
	protected Vector3 GyroInput
	{
		get
		{
			return gyroInput;
		}
		set
		{
			gyroInput = value;
		}
	}


	/// <summary> 
	/// 当前陀螺仪的输入输入类型
	/// </summary>
	public EGyroInputType gyroInputType = EGyroInputType.RotateRate;

	/// <summary> 陀螺仪输入数据的类型 </summary>
	protected EGyroInputType GyroInputType
	{
		get
		{
			return gyroInputType;
		}
		set
		{
			gyroInputType = value;
		}
	}


	///  <summary>
	/// 陀螺仪的系数 
	/// </summary>
	public float gyroFactor = 1.0f;

	/// <summary> 
	/// 陀螺仪的系数 
	/// </summary>
	protected float GyroFactor
	{
		get
		{
			return gyroFactor;
		}
		set
		{
			gyroFactor = value;
		}
	}

	// Use this for initialization
	void Start () {

		isGvrEnable = false;

		resetBtn.onClick.AddListener(OnResetBtnClick);
		switchBtn.onClick.AddListener(OnSwitchBtnClick);
		
	}

	void OnDestroy()
	{
		resetBtn.onClick.RemoveListener(OnResetBtnClick);
		switchBtn.onClick.RemoveListener(OnSwitchBtnClick);
	}

	/// <summary>
	/// 相机位置重置
	/// </summary>
	private void OnResetBtnClick()
	{
		CurEuler = Vector3.zero;
		cameraTran.transform.rotation = Quaternion.Euler(CurEuler);
	}

	/// <summary>
	/// 陀螺仪开启或禁用
	/// </summary>
	private void OnSwitchBtnClick()
	{
		isGvrEnable = !isGvrEnable;

		SetGyroScope(isGvrEnable);
	}


	/// <summary>
	/// 陀螺仪的开启与关闭
	/// </summary>
	/// <param name="isEnable"></param>
	private void SetGyroScope(bool isEnable)
	{
		if (isEnable)
		{
			//Debug.Log("NakeEye SetGyroScope 陀螺仪的开启");
			Input.gyro.enabled = true;
			CurEuler = cameraTran.transform.rotation.eulerAngles;
		}
		else
		{
			//Debug.Log("NakeEye SetGyroScope 陀螺仪的关闭");
			Input.gyro.enabled = false;
		}
	}


	/// <summary> 
	/// 更新陀螺仪数据,并计算出相应的控制数据 
	/// </summary>
	protected Vector3 SetGyrScopeType(EGyroInputType eGyroInputType)
	{
		Vector3 gyroInput = Vector3.zero;

		// 更新陀螺仪数据,并计算出控制变量
		switch (eGyroInputType)
		{ //手机上左倾斜x是负值,又倾斜x是正值。上倾斜y是负值,下倾斜y是正值
			case EGyroInputType.RotateRate:
				gyroInput = Input.gyro.rotationRate;
				break;
			case EGyroInputType.RotateRateUniased:
				gyroInput = Input.gyro.rotationRateUnbiased;
				break;
			case EGyroInputType.UserAcceleration:
				gyroInput = Input.gyro.userAcceleration;
				break;
			default:
				Debug.LogError("GyroInputTypeNot defined: " + GyroInputType);
				break;
		}

		return gyroInput;
	}


	/// <summary> 更新相机的行为 </summary>
	protected void UpdateCamera()
	{
		// 不需要gyro的z参数
		Vector3 t_gyro_input = new Vector3(-GyroInput.x, -GyroInput.y, 0);

		//Debug.Log("NakeEye 陀螺仪状态:Input.gyro.rotationRate" + Input.gyro.rotationRate+ "  Input.gyro.rotationRateUnbiased="+ Input.gyro.rotationRateUnbiased
		//    + " Input.gyro.userAcceleration "+ Input.gyro.userAcceleration);

		//Debug.Log("NakeEye 陀螺仪控制UICamera运动 input = "+ t_gyro_input+"  相机 CurEuler="+ CurEuler);

		CurEuler += t_gyro_input;

		cameraTran.transform.rotation = Quaternion.Euler(CurEuler);
	}

	// Update is called once per frame
	void Update () {

		if (isGvrEnable)
		{
			// 设置陀螺仪更新频率
			Input.gyro.updateInterval = 1.0f / gvrRate;

			// 根据陀螺仪计算相机的控制数据
			GyroInputType = EGyroInputType.RotateRate;
			GyroInput = SetGyrScopeType(GyroInputType);
			// 因值不确定范围,需增加系数控制
			GyroInput = GyroInput * GyroFactor;

			// 根据控制数据,对相机进行操作和变化
			UpdateCamera();
		}

	}
}

陀螺仪控制相机运动