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.
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.
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.
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.
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.
This feature will be out in the next release. In the meantime, here's a workaround script. Usage steps are in the file comments.
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);
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.
@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.