0
votes

I have created a VR app in Unity with Google Cardboard SDK and am now attempting to deploy it to Web and as a standalone. The game works well on iPhone and Android and the user navigates the game by turning their head and touching the screen (the "Fire1" command I believe). The problem comes when I switch platforms.

In the editor when testing, even though my computer is not strapped to my head I have been able to still play the game just as well by holding down the Alt key to turn and just clicking the screen to move. I assumed this would be the same when deploying to a standalone but I'm having a problem:

When deploying to web and standalone, the user cannot move at all thus I'm not even sure if the game is working at all - Holding the alt key does nothing and clicking the screen does nothing. They cannot play the game.

What is wrong here? Are there other inputs that I can implement specifically for standalone to replace head tracking, etc? How are other Google Cardboard VR apps deployed to web?

In my WebplayerDevice script:

//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

Errors (even when I changed the Webplayer device class to BaseVRDevice this made no difference) :enter image description here

2

2 Answers

0
votes

The key combos are only available within the Unity3d editor.

The Cardboard Unity3d SDK supports different behaviours for different platforms by loading the relevant device script under VRDevices:

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

You will see that the UnityEditorDevice.cs has the code for handling the ALT and CTRL keys.

For a web deployment, I suggest you create a new device and implement mouse movements (without a key) to look around. You can get the Cardboard SDK to load your device by editing BaseVRDevice.cs:

    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;
}
0
votes

The compile errors you are seeing are because the variables you are referring to in the Cardboard.cs script (autoUntiltHead, Screen, Device, etc) are all in a #if UNITY_EDITOR section. Change that to #if UNITY_EDITOR || UNITY_WEBPLAYER, or just remove the #if. Then you'll be able to compile.