簡體   English   中英

如何在當前設備方向啟用陀螺儀相機

[英]How to enable gyroscope camera at current device orientation

我想啟用陀螺儀控制的相機 onButtonClick 事件,但我希望它從相機當前的 position 開始。 目前,當陀螺儀啟用時,它會將相機移至新的 position(可能是設備當前的陀螺儀旋轉),而不是將其留在原處並從該點開始旋轉。

希望我說得有道理,但基本上我不希望用戶注意到他們在游戲中看到的任何變化(即由陀螺儀控制的相機,但用戶不會注意到這種變化)。 這是我正在使用的代碼:

void Update () 
{
    Quaternion attitudeFix = new Quaternion (-gyro.attitude.x, -gyro.attitude.z, -gyro.attitude.y, gyro.attitude.w);
    Quaternion offsetRotation =  initialGyroRotation * attitudeFix;
    rotation = initialRotation * offsetRotation;
    transform.rotation = rotation;
}

public void EnableGyro() 
{
    initialGyroRotation = Input.gyro.attitude;
    initialRotation = transform.rotation;

    Debug.Log("initialRotation: " + initialRotation.ToString());
    Debug.Log("transform.rotation: " + transform.rotation.ToString());
    Debug.Log("initialGyroRotation: " + initialGyroRotation.ToString());
}

**

編輯:這是一個屏幕,顯示了當用戶將設備放在臉前(肖像)並向北行駛時,我希望視圖看起來如何。 無論應用程序啟動時設備的方向如何,當手機以縱向方向向北行駛時(再次當用戶通過手機查看時),它應該是這樣的。

在此處輸入圖像描述

編輯 2:測試變得令人困惑,所以我將代碼放回您的解決方案所建議的方式。 仍然有一個小問題,但看起來這個腳本非常接近。 主要問題是當我運行每個測試時屏幕看起來不像上面的圖片,使用設備以奇怪的角度啟動應用程序。 啟動應用程序時設備的角度並不重要,指向北方和縱向時它需要看起來像上面的屏幕。

我需要做更多的測試,並且會用一個新的/干凈的項目來做。

您需要在“ Awake或“ Start功能中獲取攝像機的偏移位置。 Update功能中,將該偏移值應用於陀螺儀傳感器的值。

看來您已經知道應該使用偏移量,但是您這樣做的方式不正確。 令人困惑的部分是獲取偏移量,該偏移量需要從陀螺儀傳感器值中減去當前攝像機的旋轉角度。

要減去QuaternionInverse Quaternion ,而不只是Quaternion

Quaternion = Quaternion * Quaternion.Inverse

要添加Quaternion乘以Quaternion

Quaternion = Quaternion * Quaternion.

這是您的代碼應如下所示:

Quaternion offset;

void Awake()
{
    Input.gyro.enabled = true;
}

void Start()
{
    //Subtract Quaternion
    offset = transform.rotation * Quaternion.Inverse(GyroToUnity(Input.gyro.attitude));
}

void Update()
{
    GyroModifyCamera();
}

void GyroModifyCamera()
{
    //Apply offset
    transform.rotation = offset * GyroToUnity(Input.gyro.attitude);
}

private static Quaternion GyroToUnity(Quaternion q)
{
    return new Quaternion(q.x, q.y, -q.z, -q.w);
}

我遇到了麻煩,它在構建中不起作用這是我發現的,這個腳本已經工作了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GyroMovement : MonoBehaviour
{
    // Start is called before the first frame update

    //Movement
    [SerializeField] float speed = 3.3f;
    private float rotspeed = 90f;
    private Vector3 moveDirection = Vector3.zero;
    [SerializeField] private CharacterController controller;

    //Rotation
    private float _initialYAngle = 0f;
    private float _appliedGyroYAngle = 0f;
    private float _calibrationYAngle = 0f;
    private Transform _rawGyroRotation;
    private float _tempSmoothing;

    //settings
    private float _smoothing = 0.1f;

    private void Update(){
      //Movement
      //Vector3 move = new Vector3 (Input.acceleration.x * speed * Time.deltaTime, 0f, -Input.acceleration.z * speed * Time.deltaTime);
      //Vector3 rotMovement = transform.TransformDirection(move);
      //controller.Move(rotMovement);

      //Rotation
      ApplyGyroRotation();
      ApplyCalibration();
      transform.rotation = Quaternion.Slerp(transform.rotation, _rawGyroRotation.rotation, _smoothing);

    }

    private IEnumerator Start(){
      Input.gyro.enabled = true;
      Application.targetFrameRate = 60;
      _initialYAngle = transform.eulerAngles.y;

      _rawGyroRotation = new GameObject("GyroRaw").transform;
      _rawGyroRotation.position = transform.position;
      _rawGyroRotation.rotation = transform.rotation;
      yield return new WaitForSeconds(1f);
      StartCoroutine (CalibrateYAngle());
    }

    private IEnumerator CalibrateYAngle(){
      _tempSmoothing = _smoothing;
      _smoothing = 1f;
      _calibrationYAngle = _appliedGyroYAngle - _initialYAngle;
      yield return null;
      _smoothing = _tempSmoothing;
    }

    private void ApplyGyroRotation(){
      _rawGyroRotation.rotation = Input.gyro.attitude;
      _rawGyroRotation.Rotate(0f, 0f, 180f, Space.Self);
      _rawGyroRotation.Rotate(90f, 180f, 0f, Space.World);
      _appliedGyroYAngle = _rawGyroRotation.eulerAngles.y;
    }

    private void ApplyCalibration(){
      _rawGyroRotation.Rotate(0f, -_calibrationYAngle, 0f, Space.World);
    }

    public void SetEnabled (bool value){
      enabled = true;
      StartCoroutine(CalibrateYAngle());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM