googlevr / gvr-unity-sdk

Google VR SDK for Unity
http://developers.google.com/vr/unity/
Other
2.71k stars 1.09k forks source link

Can Not switch between VR and non-VR mode. #651

Closed clarkehe closed 6 years ago

clarkehe commented 7 years ago

I use the following code (getting from other issues) to switch between VR and non-VR mode for cardboard using Samsung S7.

  IEnumerator switchMode()
  {
        while(true)
        {
            yield return new WaitForSeconds(10.0f);

            if (mIsEnable)
            {
                yield return StartCoroutine(disableVR());
            }
            else
            {
                yield return StartCoroutine(enableVR());
            }
        }
    }

    IEnumerator disableVR()
    {
        Debug.Log(TAG + "disableVR");
        VRSettings.LoadDeviceByName("");

        VRSettings.enabled = false;
        yield return null;

        Camera.main.ResetAspect();
        mIsEnable = false;
        Debug.Log(TAG + "disableVR end");
    }

    IEnumerator enableVR()
    {
        Debug.Log(TAG + "enableVR");

        string newDevice = "cardboard";
        VRSettings.LoadDeviceByName(newDevice);

        while (true)
        {
            string loadedDevName = VRSettings.loadedDeviceName;
            Debug.Log(TAG + "enableVR, loadedDevName:" + loadedDevName);
            if ( 0 != string.Compare(loadedDevName, newDevice, true))
            {
                yield return null;
            }
            else
            {
                break;
            }
        }

        for (int i = 0; i < 5; i++)
        {
            yield return null;
        }

        VRSettings.enabled = true;
        mIsEnable = true;
        Debug.Log(TAG + "enableVR end");
    }

1、Default is VR mode. 2、Switch to not-VR mode, works. 3、Switch to VR mode. The app works, but some errors found in logcat.

I/Unity: SwitchMode, enableVR
I/Unity: SwitchMode, enableVR, loadedDevName:
D/PhoneParams: Found override: {MANUFACTURER=samsung, DEVICE=null, MODEL=SM-G9300, HARDWARE=null} : x_ppi=581, y_ppi=580
D/PhoneParams: Found override: {MANUFACTURER=samsung, DEVICE=null, MODEL=SM-G9300, HARDWARE=null} : x_ppi=581, y_ppi=580
I/GVR: [vr/gvr/capi/src/gvr.cc:95] Initialized GVR version 1.20.0
I/sensor: ASensorEventQueue_enableSensor: handle=5, name=LSM6DS3 Gyroscope Uncalibrated, ret=0
I/sensor: ASensorEventQueue_setEventRate: handle=5, name=LSM6DS3 Gyroscope Uncalibrated, delay=2500, ret=0
D/Unity: [VRDevice] Successfully created device cardboard.
I/sensor: ASensorEventQueue_enableSensor: handle=1, name=LSM6DS3 Accelerometer, ret=0
I/sensor: ASensorEventQueue_setEventRate: handle=1, name=LSM6DS3 Accelerometer, delay=2500, ret=0
I/Unity: SwitchMode, enableVR, loadedDevName:cardboard
**E/Unity: OPENGL NATIVE PLUG-IN ERROR: GL_INVALID_VALUE: Numeric argument out of range
                                                            Stacktrace is not supported on this platform. 
                                                            (Filename: ./Runtime/GfxDevice/opengles/GfxDeviceGLES.cpp Line: 383)**
I/Unity: SwitchMode, enableVR end
D/Unity: SetWindow 0 0x0
**E/Unity: OPENGL NATIVE PLUG-IN ERROR: GL_INVALID_VALUE: Numeric argument out of range
                                                            Stacktrace is not supported on this platform. 
                                                            (Filename: ./Runtime/GfxDevice/opengles/GfxDeviceGLES.cpp Line: 383)**

4、Switch to non-VR mode, works. 5、Switch to VR mode, doesNOT work. VRSettings.loadedDeviceName is always empty.

I tried with Unity 5.6.1f1, older versions of Unity doNOT work either.

Eli4sh commented 7 years ago

Hey, I had similar error logs while using Samsung Galaxy S6 with Unity 5.6.2 and GVR SDK 1.60. Updating Unity to newest stable version 2017.1 seems to fix this issue on android.

clarkehe commented 7 years ago

@Eli4sh Are you sure that you tried with Unity 5.6.2 . My workmate tells me that this issue is fixed in Unity 5.6.2.

Eli4sh commented 7 years ago

@clarkehe Yes, on 5.6.2 with the app running on Galaxy S6 OPENGL NATIVE PLUG-IN ERROR: GL_INVALID_VALUE: Numeric argument out of range popped every ms while VRSettings were enabled.

guneyozsan commented 7 years ago

The errors are still there with 5.6.2 even though the issue looks fixed and to my experience you can never know when it starts crashing randomly again. 2017.1.0f1 looks clean. https://github.com/googlevr/gvr-unity-sdk/issues/453#issuecomment-314563071

clarkehe commented 7 years ago

@Eli4sh @guneyozsan Got it. Thank you!

fredsa commented 6 years ago

For switching between VR and 2D, see https://github.com/googlevr/gvr-unity-sdk/wiki/Switching-between-VR-and-non-VR-at-runtime

@clarkehe Closing since it sounds like you're no longer seeing issues with the more recent Unity release. Please feel free to reopen if you are still seeing issues with the latest Unity 5.6 or 2017 releases.

jp-lno commented 6 years ago

HI issue the same problem but in different order. My app start in non VR mode. Toggle to VR mode work fine, but I can't back to non VR view. My toggle button, seems to be inactive on VR view.

I'm using Unity 2017.1.1p4 and GVR SDK 1.100.0

dustinkerstein commented 6 years ago

@jplongo This sounds a bit like #766 though I didn't think it existed in 2017.1.1.x but I've since moved up to 2017.1.2.x and haven't tested the latest VR Services versions with that version of Unity - Which Google VR Services version are you on? Have you tried other/older versions? If not, you might also want to try disabling "Enable GVR Library Loading" in the Developer Settings for Daydream.

jp-lno commented 6 years ago

I'm using Cardboard and only try from v1.60 to v1.100 but no way. And using older version of GVRSDK increase app crash. So I need to stay on most stable version of GVRSDK. CardBoard button work but my toggle button or even my quit button stop working when my app is in VR mode...

dustinkerstein commented 6 years ago

Ok. Have you tried Unity 2017.1.2p2 yet?

jp-lno commented 6 years ago

Nope, I've just tried different GVRSDK version. Do you think that this issue is caused by Unity instead of GVRSDK ?

jp-lno commented 6 years ago

EDIT : I've just updated Unity to 2017.1.2p2 build app but no change. Same issue... 😔

dustinkerstein commented 6 years ago

@jplongo Do you see any errors in logcat? Is this in iOS or Android?

jp-lno commented 6 years ago

No errors or specific messages. I'm on iOS 11 with my iPhone 6s as target device. But the problem is on Android too, another dev working on Android build issue the same thing.

dustinkerstein commented 6 years ago

@jplongo it's tough to say. It sounds like it could be something in your particular implementation. Have you tried building a clean project that just toggles VR mode?

jp-lno commented 6 years ago

Yes. For the moment I’m just using an empty project and only build it with Xcode. Did not embed unity project inside my iOS native app.

I think the problem don’t come specially from my toggle button. I’m using other buttons on my app and all of them stop working when VR is enabled. I can see them on screen but touch has no effect. Cardboard button are fully functional. I can select settings buttons and change cardboard profile and back to my view. So the problem is only on my custom button 😓. I guess I make a mistake somewhere. It would be simpler to solve it. But for now Can’t find where ...

dustinkerstein commented 6 years ago

@jplongo Yeah, depending on how you implemented those buttons, they may not be functional in VR mode. I use world space objects that function as buttons and raycast them on touch, but even that doesn't work on Android if the "daydream" VR device is loaded. You really shouldn't be relying on touch in VR mode though. To toggle VR mode why don't you just rely on the top left "X" button to exit VR mode, and then you can use your custom button to enable VR mode. That's how most cardboard applications function. Here's what that looks like in code:

if (Input.GetKeyDown(KeyCode.Escape)) {
     YourDisableVRMethod ();
}
jp-lno commented 6 years ago

After spending my time to try to get this button working and fail. This is exactly what I did. Try to catch cardboard back button signal and bind it. I’ve implemented this code in Update() of my class and call my method in routine to disable VR. Work well for sure but I really would like to use a custom button. So no luck at this time. But finally the issue is the same.

Many thanks for your help.

devesh2605 commented 6 years ago

I have tried the video demo scene, It works well in VR mode but the Non-VR mode does not work. Camera is horizontally stretched when switching from VR Cardboard to VR None.

I have used the previous version of GVR to switch from VR to Non-VR and used to work fine but there were issues in the Exoplayer compatibility.

I wrote the below script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VR;

public class ToggleVR : MonoBehaviour {

    void Update () {

    }

    IEnumerator SwitchToVR() {
      VRSettings.LoadDeviceByName("cardboard");
      yield return null;
      VRSettings.enabled = true;
    }

    IEnumerator SwitchOutOfVr() {
      VRSettings.LoadDeviceByName("");
      yield return null;
    }

    IEnumerator Start() {
        while (true) {
            yield return new WaitForSeconds(10f);
            yield return SwitchToVR();

            yield return new WaitForSeconds(10f);
            yield return SwitchOutOfVr();
    }
  }

    void ResetCameras() {
        for (int i = 0; i < Camera.allCameras.Length; i++) {
            Camera cam = Camera.allCameras[i];
            if (cam.enabled && cam.stereoTargetEye != StereoTargetEyeMask.None) {
                cam.transform.localRotation = Quaternion.identity;
        cam.transform.localPosition = Vector3.zero;
                Camera.main.ResetAspect ();
        }
      }
    }
}

But this is not working. Any help is appreciated.

Thanks, Devesh V

jp-lno commented 6 years ago

Where do you call ResetCameras() method ? If Camera.main.RespectAspect() is not call your problem can come from here...

Here is my toggle button script. Don't know if it's the best implementation, but it work well on my app.

public void switchMode() {
        Debug.Log("Touch toggle button");
        if (VRSettings.enabled == false) {
            Debug.Log("Start VR");
            StartCoroutine(SwitchToVR());
        }
        else {
            Debug.Log("Stop VR");
            StartCoroutine(SwitchOutOfVr());
        }
    }

    // Turn on VR
    IEnumerator SwitchToVR() {
        CanvasVRModeIsOn (true); // Hide canvas elements used in 3D mode
        yield return null; // Wait one frame!
        VRSettings.LoadDeviceByName ("cardboard");
        yield return null; // Wait one frame!
        VRSettings.enabled = true;
        yield return null; // Wait one frame!
    }

    // Turn off VR
    IEnumerator SwitchOutOfVr() {
        CanvasVRModeIsOn (false); // Restore canvas elements used in 3D mode
        yield return null; // Wait one frame!
        VRSettings.LoadDeviceByName("");
        yield return null; // Wait one frame!
        VRSettings.enabled = false;
        yield return null; // Wait one frame!
        Camera.main.ResetAspect(); // Unity bug don't provide aspect reset. So this line do the job on non VR camera )
    }

    void CanvasVRModeIsOn(bool isVR) {
        SelectObject selectObjectScript = (SelectObject)GameObject.Find ("Scripts").GetComponent<SelectObject> ();
        selectObjectScript.enabled = !isVR;

        scrollList.SetActive (false); // Don't need it even when VR is off!. Provide cleaner view mode
        showScrolllist.SetActive (!isVR);
        saveButton.SetActive (!isVR);
        quitButton.SetActive (!isVR);
        editorEmulator.SetActive (isVR);
        mainCamera.SetActive (!isVR);
        VRCamera.SetActive (isVR);

        // Hide VR button without inactive it. Needed to catch GVR back button signal
        GameObject.Find ("VRMode").transform.localScale = (isVR) ? 
            GameObject.Find ("VRMode").transform.localScale = new Vector3 (0, 0, 0) :
            GameObject.Find ("VRMode").transform.localScale = new Vector3(1, 1, 1);
    }

    // Catch GVR back button tapped. Unity consider it as Escape key pressed. Catch it and perform VR Off action =)
    void Update()
    {
        if (Input.GetKey(KeyCode.Escape))
            StartCoroutine(SwitchOutOfVr()); // Turn off VR
    }
devesh2605 commented 6 years ago

Hello @jplongo

Tried your script but does not seem to work.

jp-lno commented 6 years ago

Can you give us more informations ? I will try to help you but with more informations help is faster :)

devesh2605 commented 6 years ago

I am building a demo scene as "VRDemo"

I am using Unity 5.6.4f1 and GVR 1.6.0, I copied your script and removed the unused part.

Please find the attached link to download the project: https://drive.google.com/file/d/1q1u8KyaYPoSY-grRv7Pup4fQ9rYDC7nv/view?usp=sharing

Thanks

rusmaxham commented 6 years ago

I tried your project out and I'm not sure I understand what the problem is. I built it with 5.6.4p2 and ran on a Pixel XL running Android 8.0.0 and it appears to work properly. I'm not seeing the stretched video in non-VR mode. Can you describe the problem in more detail?

devesh2605 commented 6 years ago

Hi, Thank you for trying out the project. My test device is Samsung S7 which is running on Android 7.1 The player works fine in VR mode, but when switching to Non-VR the camera is horizontally stretched.

Please find the images link below:

https://drive.google.com/file/d/1KfNK1LF1nTzmm7MO563thXkKy_LqQ2XF/view?usp=sharing => This in VR Mode

https://drive.google.com/file/d/1Fpl7QvjUUNsBgmHzmKTde_zq0HxSoxMT/view?usp=sharing => This is NoN-VR Mode, you can see the video is horizontally stretched.

Thanks, Devesh V

jp-lno commented 6 years ago

I can test on Android but did you try to call SwitchOutVR methods in Coroutine ? I don't think the problem come from this case, but just to be sure

Did you try to update your Unity & GVR version ?

devesh2605 commented 6 years ago

@jplongo Yes, I did that. @rusmaxham He says it works on his device which is a daydream ready phone. I remeber this issues was not there in previous version of GVR SDK. I have apps which works well in VR and Non-VR mode.

Thanks, Devesh V

jp-lno commented 6 years ago

Unity 2017.2.0p1 patch seems to solve this issue ! (None) - XR: Fixed stretched background image for ARCore apps running on Samsung S8.

Not the same phone but you can try to update Unity...

rusmaxham commented 6 years ago

I'm still not sure I see the problem. By horizontally stretched I would think I would see the aspect ratio incorrect-- people look "fat" or extra wide -- but the images you posted look like they're the correct aspect ratio. If the problem is that it looks "zoomed", like you see less of the field of view than you did in VR mode, then you can adjust the camera's fieldOfView parameter to make it wider. Unfortunately, it appears that the field of view setting on the camera in Unity Editor GUI doesn't 'stick' when you exit VR mode, rather it defaults to 60º regardless of what you set in Editor. So you have to set it in C#. I added this to your ToggleVR script:

    Camera.main.ResetAspect();
    Camera.main.fieldOfView = 100;

And got this result:

screenshot_20171113-225838

Is that more of what you were expecting?

rusmaxham commented 6 years ago

Did this resolve your issue?