Search Unity

Question Quest 2 OpenXR boundary points don't change on recenter?

Discussion in 'VR' started by azathothgr, Jan 22, 2024.

  1. azathothgr


    May 3, 2019
    I'm trying to have custom placeable objects that follow the boundary, in my game.

    I've tried using inputSubsystem.TryGetBoundaryPoints together with inputSubsystem.boundaryChanged, to get the play area in the hopes of using it to determine a position and orientation for these objects that would remain stationary in relation to the boundary, but the points I'm getting don't seem to change after the first call.

    If I start in stationary mode I get back a small rectangle, that never rotates when I recenter, and when I swap to roomscale the small rectangle remains unchanged. I've confirmed that TryGetBoundaryPoints does run, and the boundaryChanged event is activated.

    Similarly, when I start in roomscale mode, I get a seemingly nice rectangle at first, but then it just stays the same and never updates with recenter, meaning it follows the camera and is immediately misaligned with the actual guardian boundary.

    Why is this happening? I'm building and running on a Quest2 (no link), using OpenXR 1.9.1, with the openXR plugin for meta support (not the oculus openxr plugin), on unity 2022.3.16f1. Switching to the oculus openxr plugin makes TryGetBoundaryPoints not return any values whatsoever, and I don't know how to use the OVR stuff to get the boundary points together with OpenXR, if even possible. It's a bit late to swap the entire game to it at this point.

    This is what I'm doing to get the boundary points :

    Code (CSharp):
    1.   void Start() {
    2.     xrloader = XRGeneralSettings.Instance?.Manager?.activeLoader;
    3.     if (xrloader != null) {
    4.       var inputSubsystem = xrloader.GetLoadedSubsystem<XRInputSubsystem>();
    5.       Debug.Log("Found xrloader");
    7.       inputSubsystem.boundaryChanged += InputSubsystem_boundaryChanged;
    8.       inputSubsystem.trackingOriginUpdated += InputSubsystem_trackingOriginChanged;
    9.     } else {
    10.       Debug.LogWarning("Couldn't get xrloader");
    11.     }
    13.   }
    15.   private void InputSubsystem_boundaryChanged(XRInputSubsystem inputSubsystem) {
    16.     Debug.Log("Boudary Changed Event");
    17.     List<Vector3> boundaryPoints = new List<Vector3>();
    18.     if (inputSubsystem.TryGetBoundaryPoints(boundaryPoints)) {
    19.       Debug.Log($"got new points {boundaryPoints.Count} ");
    20.        foreach (var point in boundaryPoints) {
    21.            Debug.Log(point);
    22.        }
    23.     } else {
    24.         Debug.LogWarning($"Could not get Boundary Points for Loader");
    25.     }
    26.   }
    I've managed to bypass this and use the camera coordinates just before a recenter event to offset these objects, which miraculously works, but just for the current session. When the game is closed and re-run, the stored offset won't be correct unless the user starts the game at an exact position and orientation, I think. There's no guarantee that the game world will be the same as before in relation to the boundary.
    laurentlavigne and MikleRe like this.