简体   繁体   English

需要带罗盘帮助的陀螺仪

[英]Gyroscope with compass help needed

I need to have a game object point north AND I want to combine this with gyro.attitude input.我需要有一个游戏对象指向北方,并且我想将它与 gyro.attitude 输入结合起来。 I have tried, unsuccessfully, to do this in one step.我曾尝试一步完成此操作,但未成功。 That is, I couldn't make any gyro script, which I found on the net, work with the additional requirement of always pointing north.也就是说,我无法制作任何我在网上找到的陀螺仪脚本,并满足始终指向北方的额外要求。 Trust me, I have tried every script I could find on the subject.相信我,我已经尝试了我能找到的关于这个主题的所有脚本。 I deduced that it's impossible and probably was stupid to think it could be done;我推断这是不可能的,认为可以做到的可能是愚蠢的; at least not this way (ie all-in-one).至少不是这种方式(即多合一)。 I guess you could say I surmised that you can't do two things at once.我猜你可以说我猜测你不能同时做两件事。 Then I thought possibly I could get the same effect by breaking-up the duties.然后我想也许我可以通过分解职责来获得同样的效果。 That is, a game object that always points north via the Y axis.也就是说,一个始终通过 Y 轴指向北方的游戏对象。 Great, got that done like this:太好了,像这样完成了:

_parentDummyRotationObject.transform.rotation = Quaternion.Slerp(_parentDummyRotationObject.transform.rotation, Quaternion.Euler(0, 360 - Input.compass.trueHeading, 0), Time.deltaTime * 5f);

And with the game object pointing north on the Y, I wanted to add the second game-object, a camera in this case, with rotation using gyro input on the X and Z axis.当游戏对象在 Y 轴上指向北方时,我想添加第二个游戏对象,在这种情况下是一个相机,在 X 轴和 Z 轴上使用陀螺仪输入进行旋转。 The reason I have to eliminate the Y axes on the camera is because I get double rotation.我必须消除相机上的 Y 轴的原因是因为我得到了双重旋转。 With two things rotating at once (ie camera and game-object), a 180 degree rotation yielded 360 in the scene.有两个东西同时旋转(即相机和游戏对象),180 度旋转在场景中产生 360 度。 Remember I need the game object to always point north (IRL) based on the device compass.请记住,我需要游戏对象始终根据设备指南针指向北 (IRL)。 If my device is pointing towards the East, then my game-object would be rotated 90 degrees in the unity scene as it points (rotation) towards the north.如果我的设备指向东方,那么我的游戏对象将在统一场景中旋转 90 度,因为它指向(旋转)北方。

I have read a lot about gyro camera controllers and one thing I see mentioned a lot is you shouldn't try to do this (limit it) on just 1 or 2 axis, when using Quaternions it's impossible when you don't know what you're doing, which I clearly do not.我已经阅读了很多关于陀螺仪相机控制器的文章,我看到很多提到的一件事是你不应该尝试在 1 或 2 轴上这样做(限制它),当使用四元数时,当你不知道你是什么时是不可能的正在做,我显然不这样做。

I have tried all 3 solutions from this solved question: Unity - Gyroscope - Rotation Around One Axis Only and each has failed to rotate my camera on 1 axis to satisfy my rotational needs.我已经从这个已解决的问题中尝试了所有 3 种解决方案: Unity - 陀螺仪 - 仅绕一个轴旋转,每个都无法在 1 个轴上旋转我的相机以满足我的旋转需求。 Figured I'd try getting 1 axis working before muddying the waters with the 2nd axis.想我会先尝试让 1 个轴工作,然后再用第 2 个轴弄混水。 BTW, my requirements are simply that the camera should only rotate on 1 axis (in any orientation) based on the X axis of my device.顺便说一句,我的要求很简单,相机应该只在基于我设备的 X 轴的 1 个轴(以任何方向)上旋转。 If I could solve for X, then I thought it'd be great to get Z gyro input to control the camera as well.如果我可以解决 X,那么我认为获得 Z 陀螺仪输入来控制相机也很棒。 So far I cannot get the camera controlled on just 1 axis (X).到目前为止,我无法仅在 1 个轴 (X) 上控制相机。 Anyway, here are my findings...无论如何,这是我的发现......

The first solution, which used Input.gyro.rotationRateUnbiased, was totally inaccurate.第一个使用 Input.gyro.rotationRateUnbiased 的解决方案完全不准确。 That is, if I rotated my device around a few times and then put my phone/device down on my desk, the camera would be in a different rotation/location each time.也就是说,如果我旋转我的设备几次,然后将我的手机/设备放在我的桌子上,相机每次都会处于不同的旋转/位置。 There was no consistency.没有一致性。 Here's my code for the first attempt/solution:这是我第一次尝试/解决方案的代码:

<code>
private void Update()
{
  Vector3 previousEulerAngles = transform.eulerAngles;
  Vector3 gyroInput = Input.gyro.rotationRateUnbiased;
  Vector3 targetEulerAngles = previousEulerAngles + gyroInput * Time.deltaTime * Mathf.Rad2Deg;
  targetEulerAngles.y = 0.0f; 
  targetEulerAngles.z = 0.0f;
  transform.eulerAngles = targetEulerAngles;
}
</code>

The second solution was very consistent in that I could rotate my device around and then put it down on the desk and the unity camera always ended up in the same location/rotation/state so-to-speak.第二种解决方案非常一致,因为我可以旋转我的设备,然后将其放在桌子上,并且统一相机总是以相同的位置/旋转/状态结束。 The problem I had was the camera would rotate on the one axis (X in this case), but it did so when I rotated my device on either the y or x axis.我遇到的问题是相机会在一个轴上旋转(在这种情况下为 X),但是当我在 y 或 x 轴上旋转我的设备时它会这样做。 Either type of rotation/movement of my phone caused the unity camera to move on the X. I don't understand why the y rotation of my phone caused the camera to rotate on X. Here is my code for solution #2:我手机的任何一种旋转/移动都会导致统一相机在 X 上移动。我不明白为什么我手机的 y 旋转会导致相机在 X 上旋转。这是我的解决方案 #2 的代码:

    private void Start()
{
  Input.gyro.enabled = true;
  startEulerAngles = transform.eulerAngles;
  startGyroAttitudeToEuler = Input.gyro.attitude.eulerAngles;
}
private void Update()
{
  Vector3 deltaEulerAngles = Input.gyro.attitude.eulerAngles - startGyroAttitudeToEuler;
  deltaEulerAngles.y = 0.0f;
  deltaEulerAngles.z = 0.0f;
  transform.eulerAngles = startEulerAngles - deltaEulerAngles;
}

The 3rd solution: I wasn't sure how to complete this last solution, so it never really worked.第三个解决方案:我不确定如何完成最后一个解决方案,所以它从来没有真正奏效。 With the 2 axis zeroed-out, the camera just flipped from facing left to right and back, or top to bottom and back;将2轴归零,相机只是从左到右和向后翻转,或从上到下和向后翻转; depending on which axis were commented out.取决于哪个轴被注释掉了。 If none of the axis were commented-out (like the original solution) the camera would gyro around on all axis.如果没有任何轴被注释掉(如原始解决方案),相机将在所有轴上旋转。 Here's my code for attempt #3:这是我尝试 #3 的代码:

    private void Start()
{
  _upVec = Vector3.zero;
  Input.gyro.enabled = true;
  startEulerAngles = transform.eulerAngles;
}
private void Update()
{
  Vector3 gyroEuler = Input.gyro.attitude.eulerAngles;
  phoneDummy.transform.eulerAngles = new Vector3(-1.0f * gyroEuler.x, -1.0f * gyroEuler.y, gyroEuler.z);
  _upVec = phoneDummy.transform.InverseTransformDirection(-1f * Vector3.forward);
  _upVec.z = 0;
//    _upVec.x = 0;
  _upVec.y = 0;
  transform.LookAt(_upVec);
//    transform.eulerAngles = _upVec;
}

Originally I thought it was my skills, but after spending a month on this I'm beginning to think that this is impossible to do.本来我以为是我的技能,但是花了一个月的时间之后我开始认为这是不可能做到的。 But that just can't be.但那是不可能的。 I know it's a lot to absorb, but it's such a simple concept.我知道要吸收很多东西,但这是一个如此简单的概念。

Any ideas?有什么想法吗?

EDIT: Thought I'd add my hierarchy:编辑:以为我会添加我的层次结构:

CameraRotator (parent with script) -> MainCamera (child) CameraRotator(带脚本的父级)-> MainCamera(子级)

CompassRotator (parent) -> Compass (child with script which rotates parent) CompassRotator(父级)-> 指南针(带有旋转父级脚本的子级)

I'd do this in the following way: Camara with default 0, 0, 0 rotation Screenshot我会通过以下方式做到这一点:Camara with default 0, 0, 0 rotation Screenshot

Object placed at the center of the default position of the camera.放置在相机默认位置中心的对象。

Script for the Camera:相机脚本:

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

public class NewBehaviourScript : MonoBehaviour
{
    Camera m_MainCamera;
    // Start is called before the first frame update
    void Start()
    {
        // Disable the sleep timeout during gameplay. 
        // You can re-enable the timeout when menu screens are displayed as necessary. 
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
        // Enable the gyroscope. 
        if (SystemInfo.supportsGyroscope)
        {
            Input.gyro.enabled = true;
        }
        m_MainCamera = Camera.main;
        m_MainCamera.enabled = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (m_MainCamera.enabled)
        {
            // First - Grab the Gyro's orientation. 
            Quaternion tAttitude = Input.gyro.attitude;
            // The Device uses a 'left-hand' orientation, we need to transform it to 'right-hand'
            Quaternion tGyro = new Quaternion(tAttitude.x, tAttitude.y, -tAttitude.z, -tAttitude.w);

            // the gyro attitude is tilted towards the floor and upside-down reletive to what we want in unity.  
            // First Rotate the orientation up 90deg on the X Axis, then 180Deg on the Z to flip it right-side up. 
            Quaternion tRotation = Quaternion.Euler(-90f, 0, 0) * tGyro;
            tRotation = Quaternion.Euler(0, 0, 180f) * tRotation;

            // You can now apply this rotation to any unity camera!
            m_MainCamera.transform.localRotation = tRotation;
        }
    }
}

With this script my Object always face SOUTH no matter what.有了这个脚本,我的对象无论如何总是面向南。

If you want the object to face NORTH you just have to turn the view 180º on the Y axis as a last rotation:如果您希望对象面向北,您只需将 Y 轴上的视图旋转 180º 作为最后一次旋转:

Quaternion tRotation = Quaternion.Euler(-90f, 0, 0) * tGyro;
tRotation = Quaternion.Euler(0, 0, 180f) * tRotation;
//Face NORTH:
tRotation = Quaternion.Euler(0,180f, 0) * tRotation;

Hope this might help ;)希望这可能会有所帮助;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM