Search Unity

Handling recentering correctly

Discussion in 'Daydream' started by ezra_vr, Feb 8, 2017.

  1. ezra_vr

    ezra_vr

    Joined:
    Jan 23, 2016
    Posts:
    8
    I'm trying to adhere to Daydream UX requirement UX-D6, which says that my app should handle recentering events by recording the user's current orientation relative to the world, and then rotating the world after a recentering operation is complete in order to keep the user's relative orientation the same. Or, more plainly: the user should be looking at the same thing they were looking at before the recentering operation occurred.

    According to the Controller API Basics page, I should be monitoring for GvrController.Recentering to know when the user has started the recentering operation. I'm checking for GvrController.Recentering during every frame's Update(), but unfortunately, it's never set to true. GvrController.Recentered does work, but by the time GvrController.Recentered is true, several frames have passed since the coordinate system was changed and there's no proper way to know exactly when the coordinate system switched over.

    Is GvrController.Recentering just broken? Is there a different way to handle this? I've tested with both the GoogleVR 1.10 and 1.20 SDKs, using Unity 5.4.2f2-GVR13.
     
  2. mira_leung

    mira_leung

    Official Google Employee

    Joined:
    May 17, 2016
    Posts:
    70
    You shouldn't need to handle recentering the headset explicitly, since VrCore will take care of that for you. For example, try building GVRDemo with the GvrViewer prefab disabled, and observe that the headset still recenters.

    The headset just needs to be reset to the origin, i.e. the first thing you were looking at when the app started up.
     
  3. ezra_vr

    ezra_vr

    Joined:
    Jan 23, 2016
    Posts:
    8
    The behavior you're describing (headset resets to the origin) is indeed what happens in my app. It just seems to be in conflict with this passage from UX-D6:

    "If the app involves your user moving around a 360° environment with no strong notion of which way is "forward" (for example, StreetView), then on recenter your app must preserve the user’s orientation with respect to the environment at the time of the recenter. When the user starts the recenter operation, the app should compute the offset needed to correct the controller’s position, and then, before drawing the next frame, rotate the environment by said offset. From the user’s perspective, the controller is now recentered and their orientation with respect to the environment hasn’t changed. That is, the object that was in front of the user before the recenter is the same object that is in front of the user after the recenter."

    For context, my app is a panorama viewer, which means that it doesn't have a strong notion of "forward" -- similar to StreetView in the quoted passage.
     
  4. mira_leung

    mira_leung

    Official Google Employee

    Joined:
    May 17, 2016
    Posts:
    70
    To clarify, you want to recenter the controller but not the headset?
     
  5. ezra_vr

    ezra_vr

    Joined:
    Jan 23, 2016
    Posts:
    8
    I'm not really looking to do anything beyond complying with the UX guidelines, so if I'm misunderstanding what UX-D6 means, I apologize. But yes, that's my reading of the quoted section above: in an app with no real "forward" direction, recentering should reset the controller's position while keeping the headset looking at the same object it was looking at before the recentering operation.
     
  6. frigi

    frigi

    Joined:
    Jul 15, 2014
    Posts:
    9
    I'm very interested in this as well! I've had it working in the editor at one point but it wouldn't work on the device. IIRC the timings of the recentered event and the actual buttonUp were different between editor and device and hence prevented me from finding a solution.
     
  7. mira_leung

    mira_leung

    Official Google Employee

    Joined:
    May 17, 2016
    Posts:
    70
    This feature will be out in the next release. In the meantime, here's a workaround script. Usage steps are in the file comments.
     

    Attached Files:

  8. mira_leung

    mira_leung

    Official Google Employee

    Joined:
    May 17, 2016
    Posts:
    70
    You will also need these patches:

    GvrController.cs: Add the following

    public static bool HomeButtonDown {
    get {
    return instance != null ? instance.controllerState.homeButtonDown : false;
    }
    }

    public static bool HomeButtonState {
    get {
    return instance != null ? instance.controllerState.homeButtonState : false;
    }
    }

    ControllerState.cs: Add the following, with the appropriate assignments in that class's methods.
    internal bool homeButtonDown = false;
    internal bool homeButtonState = false;

    AndroidNativeControllerProvider.cs: Add this to ReadState:

    outState.homeButtonDown =
    0 != gvr_controller_state_get_button_down(statePtr, GVR_CONTROLLER_BUTTON_HOME);
    outState.homeButtonState =
    0 != gvr_controller_state_get_button_state(statePtr, GVR_CONTROLLER_BUTTON_HOME);
     
    Tuism likes this.
  9. ezra_vr

    ezra_vr

    Joined:
    Jan 23, 2016
    Posts:
    8
    Thanks! The proposed workaround is effective, with the exception that the recentering fade-out doesn't seem to reliably wait for an entire frame before fading back in. Consequently, about half the time, the view fades back in before the re-orientation has taken effect, and the user sees the view quickly jump to the new orientation. It'd be nice if that happened before the view faded back in, as it's a little jarring to see.
     
  10. mira_leung

    mira_leung

    Official Google Employee

    Joined:
    May 17, 2016
    Posts:
    70
    @ezra_vr Thanks for the feedback, we'll investigate internally.
     
    ezra_vr likes this.
  11. fmielke

    fmielke

    Joined:
    Oct 17, 2016
    Posts:
    35
    Great discussion! I make use of that, too!
     
  12. ezra_vr

    ezra_vr

    Joined:
    Jan 23, 2016
    Posts:
    8
    @mira_leung Any updates on this? I submitted my app for Daydream approval without any of this re-centering functionality, and it was rejected because it needs to handle re-centering. I appreciate the workaround you posted, but due to the issue I mentioned above (the user's viewpoint jumping to a new rotation after the screen has already faded in), I'm waiting for a more polished solution.
     
    pfreema1 likes this.