Forum Discussion
TortoiseIsFaste
5 years agoExplorer
How to disable Quest recentering in Unity XR 2019.3?
Previously we could just call `ovrp_SetReorientHMDOnControllerRecenter(false);`, and set the tracking level to stage, but using the XR Plugin workflow, it looks like even though this method returns true, it's not honored, and the recenter will still teleport you manually.
The comments layout why you would want to disable it:
> /// If true, the Reset View in the universal menu will cause the pose to be reset. This should generally be
Also, `ovrp_GetAppShouldRecenter()` seems to always return false, even during a recentering operation. So I have no idea why AllowRecenter used to work on the Quest, but the calls appear to not be working now, in 2019.3.
So, in 2019.3, using the new XR Plugin system -- how can I disable location recentering, so that the player can't use it to teleport behind walls, etc.?
The comments layout why you would want to disable it:
> /// If true, the Reset View in the universal menu will cause the pose to be reset. This should generally be
> /// enabled for applications with a stationary position in the virtual world and will allow the View Reset
> /// command to place the person back to a predefined location (such as a cockpit seat).
> /// Set this to false if you have a locomotion system because resetting the view would effectively teleport
> /// the player to potentially invalid locations.
Also, `ovrp_GetAppShouldRecenter()` seems to always return false, even during a recentering operation. So I have no idea why AllowRecenter used to work on the Quest, but the calls appear to not be working now, in 2019.3.
So, in 2019.3, using the new XR Plugin system -- how can I disable location recentering, so that the player can't use it to teleport behind walls, etc.?
5 Replies
- TortoiseIsFasteExplorerFYI, (for anyone googling, that wound up here): I double posted this to the OculusDev reddit; and it looks like it got some official traction there (also I can't post links, so you'll have to fix this on your own): www.reddit-dot-com/r/oculusdev/comments/f792jy/how_to_disable_oculus_quest_recentering_in_unity/
- emalafeewProtege
I implemented a version of that thread's suggestion here. Instead of calculating eigenvectors I just use the first and middle points of the boundary to determine its position and rotation change, and apply that in reverse to a CameraOffset object to keep the Camera still during oculus recenter events. To actually recenter, call the public Recenter() function.
Note the recommended way to deal with this problem is to use Stage Tracking space (Oculus Guardian System | Oculus Developers), but we also needed a way to locally recenter to change virtual camera angles for Mixed Reality Capture.
public class RecenterHelper() { Transform CameraOffset; // set to parent of main Camera Vector3[] mBoundary; void Start() { OVRManager.display.RecenteredPose += OculusRecenter; } void RotateXZ(Vector3 a, float rot, out Vector3 b) { // rot is clockwise radians var sin = Mathf.Sin(rot); var cos = Mathf.Cos(rot); b = new Vector3(a.x*cos + a.z*sin, a.y, -a.x*sin + a.z*cos); } // Instead of recentering, don't recenter! void OculusRecenter() { var points = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.OuterBoundary); if (mBoundary != null && points.Length == mBoundary.Length) { var deltaPos0 = mBoundary[0] - points[0]; var newPointMid = points[points.Length/2] + deltaPos0; var vec0ToOldMid = mBoundary[points.Length/2] - mBoundary[0]; var vec0ToNewMid = newPointMid - mBoundary[0]; var angOldMid = Mathf.Atan2(vec0ToOldMid.z, vec0ToOldMid.x); var angNewMid = Mathf.Atan2(vec0ToNewMid.z, vec0ToNewMid.x); var deltaRot = angOldMid - angNewMid; while (deltaRot > Mathf.PI) deltaRot -= 2*Mathf.PI; while (deltaRot < -Mathf.PI) deltaRot += 2*Mathf.PI; var reverse0 = -points[0]; RotateXZ(reverse0, -deltaRot, out reverse0); reverse0 += points[0]; var pos = CameraOffset.TransformPoint(deltaPos0 + reverse0); pos = CameraOffset.parent.InverseTransformPoint(pos); CameraOffset.localPosition = pos; var angs = CameraOffset.localEulerAngles; angs.y -= deltaRot * Mathf.Rad2Deg; CameraOffset.localEulerAngles = angs; } mBoundary = points; } public void Recenter() { mBoundary = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.OuterBoundary); Transform cam = Camera.main.transform; float yawOffset = -cam.localEulerAngles.y; float ang = -yawOffset * Mathf.Deg2Rad; float sinAng = Mathf.Sin(ang); float cosAng = Mathf.Cos(ang); float xOffset = cam.localPosition.z * sinAng - cam.localPosition.x * cosAng; float zOffset = -cam.localPosition.z * cosAng - cam.localPosition.x * sinAng; CameraOffset.localPosition = new Vector3(xOffset, 0, zOffset); CameraOffset.localEulerAngles = new Vector3(0, yawOffset, 0); } }- glenneroovyProtege
It looks like your solution will soon no longer be supported, as the following has been marked as deprecated by Oculus SDK since at least 2 updates:
OVRBoundary.BoundaryType.OuterBoundary
I have asked support for some assistance or at least clarification, however they responded with "we can not provide support for projects".
- emalafeewProtege
It may still work with BoundaryType.PlayArea if they optimally align that to the outer boundary.
Note BoundaryType.OuterBoundary is only deprecated for the OpenXR backend, but seems like all new features (like passthrough) will require that.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 1 year ago
- 4 years agoAnonymous
- 5 months ago