Gyroscope with compass help needed

↘锁芯ラ 提交于 2019-12-07 17:03:50

问题


I need to have a game object point north AND I want to combine this with gyro.attitude input. 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 (i.e. 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. 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. The reason I have to eliminate the Y axes on the camera is because I get double rotation. With two things rotating at once (i.e. camera and game-object), a 180 degree rotation yielded 360 in the scene. Remember I need the game object to always point north (IRL) based on the device compass. 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.

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.

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. Figured I'd try getting 1 axis working before muddying the waters with the 2nd axis. 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. If I could solve for X, then I thought it'd be great to get Z gyro input to control the camera as well. So far I cannot get the camera controlled on just 1 axis (X). Anyway, here are my findings...

The first solution, which used Input.gyro.rotationRateUnbiased, was totally inaccurate. 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. 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:

    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; 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:

    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)

CompassRotator (parent) -> Compass (child with script which rotates parent)

来源:https://stackoverflow.com/questions/46943868/gyroscope-with-compass-help-needed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!