【问题标题】:Unity Cardboard Orientation Landscape Right Upside DownUnity Cardboard Orientation Landscape Right Upside Down
【发布时间】:2015-08-25 09:15:13
【问题描述】:

您好,我有一个 Unity 应用程序,它使用 google Cardboard SDK 来启用立体视图,因此我将拥有一个支持 VR 的应用程序。我的应用程序运行良好。

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

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

谢谢。

【问题讨论】:

    标签: c# unity3d screen-orientation google-cardboard virtual-reality


    【解决方案1】:

    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),因为此代码不会正确显示。

    【讨论】:

      【解决方案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);
          }
        }
      

      【讨论】:

        【解决方案3】:

        你可以添加:

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

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

        【讨论】:

          【解决方案4】:
                  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 上是这样写的

          【讨论】:

            【解决方案5】:

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

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

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

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

            -

            另请注意,这也适用于具有 Cardboard 的 VR 应用程序 和其他人一样。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-11-22
              • 2020-04-02
              • 2020-12-23
              • 2019-09-29
              • 2012-12-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多