3

嗨,我有一个 Unity 应用程序,它使用谷歌 Cardboard SDK 来启用立体视图,所以我将有一个支持 VR 的应用程序。我的应用程序运行良好。

但是如果我将播放器设置方向设置为自动方向,只允许横向左侧和横向右侧,则会出现问题。当它在左侧横向时,一切正常,但是当它在右侧横向时,纸板视图将转动 180 度(设置按钮移动到屏幕底部),但我的统一对象没有。因此我有一个颠倒的物体。

有什么方法可以解决这个问题?

谢谢。

4

5 回答 5

3

SDK 用于读取陀螺仪的本机代码似乎仅针对横向左方向进行了硬编码。这可以通过编辑 BaseCardboardDevice.cs 并将 UpdateState() 的定义替换为以下代码来解决:

private Quaternion fixOrientation;

public override void UpdateState() {
  GetHeadPose(headData, Time.smoothDeltaTime);
  ExtractMatrix(ref headView, headData);
  headPose.SetRightHanded(headView.inverse);

  // Fix head pose based on device orientation (since native code assumes Landscape Left).
  switch (Input.deviceOrientation) {
    case DeviceOrientation.LandscapeLeft:
      fixOrientation = Quaternion.identity;
      return;
    case DeviceOrientation.LandscapeRight:
      fixOrientation = Quaternion.Euler(0, 0, 180);
      break;
  }
  headPose.Set(headPose.Position, headPose.Orientation * fixOrientation);
}

我也建议在 Cardboard 设置中关闭 Neck Model Scale(将其设置为 0),因为此代码不会正确显示。

于 2015-09-02T04:11:12.710 回答
2

我已经解决了这个问题,这是解决方案(适用于 Cardboard v0.5.2)

首先,根据 smd 的建议,您需要在 BaseCardboardDevice / UpdateState() 中应用方向调整。但是,您应该检查 ScreenOrientation 而不是 DeviceOrientation。代码如下:

public override void UpdateState() {

    ProcessEvents();
    GetHeadPose(headData);
    ExtractMatrix(ref headView, headData);
    headPose.SetRightHanded(headView.inverse);

    if (Screen.orientation == ScreenOrientation.LandscapeRight) {
        headPose.Set(headPose.Position, headPose.Orientation * Quaternion.Euler(0, 0, 180));                           // Workaround
}

这将修复方向,但这还不够,因为在 Cardboard Recenter() 之后您将面临错误的方向。要解决此问题,您还需要在 CardboardHead / UpdateHead() 方法中应用旋转,代码如下:

private void UpdateHead() {

    if (updated) {  // Only one update per frame, please.
      return;
    }
    updated = true;
    Cardboard.SDK.UpdateState();

    if (trackRotation) {
      var rot = Cardboard.SDK.HeadPose.Orientation;

      if (Screen.orientation == ScreenOrientation.LandscapeRight) {
        rot = Quaternion.Euler(0, 180, 0) * rot; //           << Workaround
      }

      if (target == null) {
        transform.localRotation = rot;
      } else {
        transform.rotation = target.rotation * rot;
      }
    }

    if (trackPosition) {
      Vector3 pos = Cardboard.SDK.HeadPose.Position;
      if (target == null) {
        transform.localPosition = pos;
      } else {
        transform.position = target.position + target.rotation * pos;
      }
    }

    if (OnHeadUpdated != null) {
      OnHeadUpdated(gameObject);
    }
  }
于 2016-01-19T13:54:43.473 回答
1

您可以添加:

headPose.Set(headPose.Position, headPose.Orientation * Quaternion.Euler(0,0,180));

在 BaseCardboardDevice 类的 UpdateState() 和。无论我如何打开我尝试过的设备,它都为我解决了这个问题。Unity 5 纸板 SDK v0.5.1

于 2015-09-07T17:36:36.773 回答
1
        var fixOrientation = Quaternion.identity;
        // Fix head pose based on device orientation (since native code assumes Landscape Left).
        switch (Input.deviceOrientation) {
        case DeviceOrientation.LandscapeLeft:
            fixOrientation = Quaternion.identity;
            break;
        case DeviceOrientation.LandscapeRight:
            fixOrientation = Quaternion.Euler(0, 0, 180);
            break;
        default:
            Debug.Log ("Error No Orientation" + Input.deviceOrientation.ToString ());
            break;
        }
        headPose.Set(headPose.Position, headPose.Orientation * fixOrientation);

现在,Cardboard SDK 变成了 GoogleVR,所以我在 GvrDevice.cs 上是这样写的

于 2016-07-05T03:53:15.673 回答
0

让您的应用程序同时出现在 LandscapeLeft 和 LandscapeRight 中的一种方法是,在 Start 方法中按以下顺序启用屏幕设置:

void Start () {
     Screen.orientation = ScreenOrientation.Landscape;
     Screen.orientation = ScreenOrientation.AutoRotation;
     Screen.autorotateToPortrait = false;
     Screen.autorotateToPortraitUpsideDown = false;
}

基本上你强制一侧,然后启用自动旋转,然后防止旋转是纵向的。

请注意,这样您的应用程序可以在两种地形上运行,因此您只需向左或向右旋转屏幕。

-

另请注意,这也适用于一个使用 Cardboard 的VR 应用程序。

于 2017-11-04T21:50:56.640 回答