【问题标题】:Unity: can't move when deploying Google Cardboard VR app as standalone/web?Unity:将 Google Cardboard VR 应用程序部署为独立/网络时无法移动?
【发布时间】:2016-05-11 02:28:35
【问题描述】:

我在 Unity 中使用 Google Cardboard SDK 创建了一个 VR 应用,现在正尝试将其部署到 Web 并作为独立应用。该游戏在 iPhone 和 Android 上运行良好,用户通过转动头部并触摸屏幕来导航游戏(我相信是“Fire1”命令)。当我切换平台时,问题就来了。

在编辑器中测试时,即使我的电脑没有绑在头上,我仍然可以通过按住 Alt 键转动并单击屏幕移动来玩游戏。我认为在部署到独立设备时这将是相同的,但我遇到了问题:

当部署到网络和单机版时,用户根本无法移动,因此我什至不确定游戏是否正常运行 - 按住 alt 键什么都不做,点击屏幕什么也不做。他们不能玩游戏。

这里有什么问题?我是否可以专门为独立实现其他输入以替换头部跟踪等?其他 Google Cardboard VR 应用是如何部署到网络上的?

在我的 WebplayerDevice 脚本中:

//For web support

#if UNITY_WEBPLAYER

using UnityEngine;
using System.Runtime.InteropServices;
using System.Collections.Generic;

public class CardboardWebplayerDevice : BaseCardboardDevice {

    // Simulated neck model.  Vector from the neck pivot point to the point between the eyes.
    private static readonly Vector3 neckOffset = new Vector3(0, 0.075f, 0.08f);

    // Use mouse to emulate head in the editor.
    private float mouseX = 0;
    private float mouseY = 0;
    private float mouseZ = 0;

    public override void Init() {
        Input.gyro.enabled = true;
        Debug.Log ("ITS WEB!!");

    }

    public override bool SupportsNativeDistortionCorrection(List<string> diagnostics) {
        return false;  // No need for diagnostic message.
    }

    public override bool SupportsNativeUILayer(List<string> diagnostics) {
        return false;  // No need for diagnostic message.
    }

    // Since we can check all these settings by asking Cardboard.SDK, no need
    // to keep a separate copy here.
    public override void SetUILayerEnabled(bool enabled) {}
    public override void SetVRModeEnabled(bool enabled) {}
    public override void SetDistortionCorrectionEnabled(bool enabled) {}
    public override void SetStereoScreen(RenderTexture stereoScreen) {}
    public override void SetSettingsButtonEnabled(bool enabled) {}
    public override void SetAlignmentMarkerEnabled(bool enabled) {}
    public override void SetVRBackButtonEnabled(bool enabled) {}
    public override void SetShowVrBackButtonOnlyInVR(bool only) {}
    public override void SetNeckModelScale(float scale) {}
    public override void SetAutoDriftCorrectionEnabled(bool enabled) {}
    public override void SetElectronicDisplayStabilizationEnabled(bool enabled) {}
    public override void SetTapIsTrigger(bool enabled) {}

    private Quaternion initialRotation = Quaternion.identity;

    private bool remoteCommunicating = false;
    private bool RemoteCommunicating {
        get {
            if (!remoteCommunicating) {
remoteCommunicating = Vector3.Dot(Input.gyro.rotationRate, Input.gyro.rotationRate) > 0.05;
            }
            return remoteCommunicating;
        }
    }

    public override void UpdateState() {
        Quaternion rot;
        if (Cardboard.SDK.UseUnityRemoteInput && RemoteCommunicating) {
            var att = Input.gyro.attitude * initialRotation;
            att = new Quaternion(att.x, att.y, -att.z, -att.w);
            rot = Quaternion.Euler(90, 0, 0) * att;
        } else {
            bool rolled = false;
            if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) {
                mouseX += Input.GetAxis("Mouse X") * 5;
                if (mouseX <= -180) {
                    mouseX += 360;
                } else if (mouseX > 180) {
                    mouseX -= 360;
                }
                mouseY -= Input.GetAxis("Mouse Y") * 2.4f;
                mouseY = Mathf.Clamp(mouseY, -85, 85);
            } else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) {
                rolled = true;
                mouseZ += Input.GetAxis("Mouse X") * 5;
                mouseZ = Mathf.Clamp(mouseZ, -85, 85);
            }
            if (!rolled && Cardboard.SDK.autoUntiltHead) {
                // People don't usually leave their heads tilted to one side for long.
                mouseZ = Mathf.Lerp(mouseZ, 0, Time.deltaTime / (Time.deltaTime + 0.1f));
            }
            rot = Quaternion.Euler(mouseY, mouseX, mouseZ);
        }
        var neck = (rot * neckOffset - neckOffset.y * Vector3.up) * Cardboard.SDK.NeckModelScale;
        headPose.Set(neck, rot);

        triggered = Input.GetMouseButtonDown(0);
        tilted = Input.GetKeyUp(KeyCode.Escape);
    }


    public override void PostRender() {
        // Do nothing.
    }

    public override void UpdateScreenData() {
        Profile = CardboardProfile.GetKnownProfile(Cardboard.SDK.ScreenSize, Cardboard.SDK.DeviceType);
        ComputeEyesFromProfile();
        profileChanged = true;
    }

    public override void Recenter() {
        mouseX = mouseZ = 0;  // Do not reset pitch, which is how it works on the phone.
        if (RemoteCommunicating) {
            //initialRotation = Quaternion.Inverse(Input.gyro.attitude);
        }
    }
}
#endif

错误(即使我将 Webplayer 设备类更改为 BaseVRDevice 也没有什么区别):

【问题讨论】:

    标签: web unity3d google-cardboard virtual-reality


    【解决方案1】:

    您看到的编译错误是因为您在 Cardboard.cs 脚本中引用的变量(autoUntiltHead、Screen、Device 等)都在 #if UNITY_EDITOR 部分中。将其更改为 #if UNITY_EDITOR || UNITY_WEBPLAYER,或者只是删除#if。然后就可以编译了。

    【讨论】:

      【解决方案2】:

      按键组合仅在 Unity3d 编辑器中可用。

      Cardboard Unity3d SDK通过加载VRDevices下的相关设备脚本,支持不同平台的不同行为:

      https://github.com/googlesamples/cardboard-unity/blob/master/Cardboard/Scripts/VRDevices

      您将看到 UnityEditorDevice.cs 包含处理 ALT 和 CTRL 键的代码。

      对于网络部署,我建议您创建一个新设备并实现鼠标移动(无需按键)以环顾四周。您可以通过编辑 BaseVRDevice.cs 让 Cardboard SDK 加载您的设备:

          public static BaseVRDevice GetDevice() {
              if (device == null) {
          #if UNITY_EDITOR
                device = new UnityEditorDevice();
          #elif ANDROID_DEVICE
                device = new CardboardAndroidDevice();
          #elif IPHONE_DEVICE
                device = new CardboardiOSDevice();
          // Support your device here:
          #elif UNITY_WEBPLAYER
                device = new CardboardWebplayerDevice();
          #else
                throw new InvalidOperationException("Unsupported device.");
          #endif
              }
              return device;
      }
      

      【讨论】:

      • 好的,我已经将以上内容写入 BaseVRDevice.cs 并创建了 CardboardWebplayerDevice 脚本。我对此比较陌生,但是我基本上将 UnityEditorDevice.cs 中的代码复制并粘贴到我的网络播放器设备脚本中,以便用户控件是相同的。我的 CardboardWebplayerDevice.cs 代码在我上面的问题中。当我尝试为 web 构建时,我遇到了大量错误(我附上了截图)。我应该在这里做什么?
      • 你只需要去掉移动代码。如果您不介意外部链接 - 我已将其作为替代脚本:talesfromtherift.com/unity-vr-editor-mouse-look-script
      • 去掉运动代码是什么意思?我不需要包括所有其他覆盖方法吗?抱歉,这是新手 - 现在查看 VRMouseLook.cs 脚本。你从那个脚本中得到了什么并放在 CardboardWebplayerDevice 中?我从 UnityEditorDevice 中保留了多少?
      • 您是否将 CardboardWebplayerDevice 设为 BaseVRDevice 或 BaseCardboardDevice 的子类?
      猜你喜欢
      • 1970-01-01
      • 2016-02-04
      • 2015-09-10
      • 2016-05-14
      • 1970-01-01
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多