Building hybrid apps in Unity

Hybrid apps support both 2D (non-VR) and VR modes.

  • Developers can choose whether a hybrid app starts in 2D or in VR mode. However, Daydream apps must be configured to start in VR mode when launched from Daydream home.

  • Developers are responsible for providing users a way to switch between modes.

  • While in 2D, apps can optionally allow users to preview content inside a Magic Window view, which may or may not be full screen.

Prerequisites

To enable switching between 2D and VR at runtime in your app:

  1. Ensure Player Settings > Android/iOS > Virtual Reality Supported is checked.

  2. Add the following entries in Player Settings > Android/iOS > Virtual Reality SDKs:

    • Add None to support 2D mode in your app.

    • Add Daydream and/or Cardboard to support VR mode in your app.

  3. Order the SDK options to control which mode your app starts in when launched from the 2D desktop launcher:

    • To start in 2D mode, put None first.

    • To start in VR mode, put Daydream or Cardboard first.

Switching to VR mode at runtime

To enter VR mode at runtime, load the desired VR device, wait one frame, then enable VR mode. Here is an example:

// Call via `StartCoroutine(SwitchToVR())` from your code. Or, use
// `yield SwitchToVR()` if calling from inside another coroutine.
IEnumerator SwitchToVR() {
  // Device names are lowercase, as returned by `XRSettings.supportedDevices`.
  string desiredDevice = "daydream"; // Or "cardboard".

  // Some VR Devices do not support reloading when already active, see
  // https://docs.unity3d.com/ScriptReference/XR.XRSettings.LoadDeviceByName.html
  if (String.Compare(XRSettings.loadedDeviceName, desiredDevice, true) != 0) {
    XRSettings.LoadDeviceByName(desiredDevice);

    // Must wait one frame after calling `XRSettings.LoadDeviceByName()`.
    yield return null;
  }

  // Now it's ok to enable VR mode.
  XRSettings.enabled = true;
}

Switching to 2D mode at runtime

To leave VR mode at runtime, load the "None" device, wait one frame, then reset camera transform and settings. Here is an example:

// Call via `StartCoroutine(SwitchTo2D())` from your code. Or, use
// `yield SwitchTo2D()` if calling from inside another coroutine.
IEnumerator SwitchTo2D() {
  // Empty string loads the "None" device.
  XRSettings.LoadDeviceByName("");

  // Must wait one frame after calling `XRSettings.LoadDeviceByName()`.
  yield return null;

  // Not needed, since loading the None (`""`) device takes care of this.
  // XRSettings.enabled = false;

  // Restore 2D camera settings.
  ResetCameras();
}

// Resets camera transform and settings on all enabled eye cameras.
void ResetCameras() {
  // Camera looping logic copied from GvrEditorEmulator.cs
  for (int i = 0; i < Camera.allCameras.Length; i++) {
    Camera cam = Camera.allCameras[i];
    if (cam.enabled && cam.stereoTargetEye != StereoTargetEyeMask.None) {

      // Reset local position.
      // Only required if you change the camera's local position while in 2D mode.
      cam.transform.localPosition = Vector3.zero;

      // Reset local rotation.
      // Only required if you change the camera's local rotation while in 2D mode.
      cam.transform.localRotation = Quaternion.identity;

      // No longer needed, see issue github.com/googlevr/gvr-unity-sdk/issues/628.
      // cam.ResetAspect();

      // No need to reset `fieldOfView`, since it's reset automatically.
    }
  }
}

Detecting whether your app was launched from VR

Daydream apps can be launched from VR or from the 2D launcher. See the Android Manifest for Google VR reference for a list of supported Android intent filters that enable launching from VR or 2D.

Unity ensures that hybrid Daydream apps launched from VR automatically start in VR mode, even if the None device is listed above the Daydream VR device in Player Settings > Android/iOS > Virtual Reality SDKs. This helps ensure that your app meets Daydream design requirement UX-D9.

To detect whether your app was launched from VR at runtime, use GvrIntent.IsLaunchedFromVr(). This method returns true if the Android intent that launched your app contains the android.intent.extra.VR_LAUNCH extra, indicating that your app was launched from VR.