Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Can we reuse user`s VR boundaries?

Discussion in 'VR' started by Adrien_Triangles, Jan 29, 2020.

  1. Adrien_Triangles

    Adrien_Triangles

    Joined:
    Feb 4, 2016
    Posts:
    35
    Hi!

    I would like to know if we can (and how :) ?) reuse the VR boundaries our VR user has to define before starting playing ?
    So the Guardian for Quest users, and the play area for SteamVR users etc.

    Ideally I would reuse these so my users don`t have to make a new one for my application...

    What I`m looking for is like a flat geometry, or a curve? Or points and index so I can then generate something out of it..?

    Also if anyone has reference of like other games/apps doing so I`d appreciate !

    Thanks
     
    JoeStrout likes this.
  2. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    Fangh, tenconmar, colinleet and 2 others like this.
  3. Adrien_Triangles

    Adrien_Triangles

    Joined:
    Feb 4, 2016
    Posts:
    35
    Thank you this will come in very practical when its time comes ! :)
     
  4. Adrien_Triangles

    Adrien_Triangles

    Joined:
    Feb 4, 2016
    Posts:
    35
    Do you have a tool in mind when it comes to procedurally model an environment depending on the Boundary Points?
    I can think of Houdini but this won't be available at runtime.
    Spline driven models that would use the Boundary points could get pretty advanced quickly, but I want to gain immersion by having some more variations on the wall so either edit this pline, either on the non reach-able parts (high building with different roofs setups etc.) To be short I'd like more than splined models. Tryin
    I know a bit of Bolt I could try this in there, would you have anything easier in mind for achieving this or similar ?
     
  5. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    Wow! Does this work with Oculus / Quest as is?
     
  6. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    Yes!
    But only in the new Plugin Architecture packages, Oculus was implemented in V1.0.0 of the package.
     
  7. Enzo-z1

    Enzo-z1

    Joined:
    Jan 28, 2019
    Posts:
    2
    Hello guys !

    I've been looking for a while after a solution for this.
    I tried your method @StayTalm_Unity but i don't understand something. TryGetBoundaryPoints is a bool method, wich not send back any Vector3 stuff.

    I also tried this method (and also lots of desperate things as retrieving the points directly from the Boundary Rendering gameobject) :

    if (OVRManager.boundary.GetConfigured())
    {
    Vector3[] boundaryPosition = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.OuterBoundary);
    }

    But it keeps returning an empty array. I searched in the OVRBoundary code and don't get oculus devs logic.

    If someone has some code to leak... ^^ it would help me!

    If I further don't find a solution, I will try to change versions of oculus integration/packages/plugins/whatever..
     
  8. throzen

    throzen

    Joined:
    Jun 11, 2015
    Posts:
    6
    Hey. I was trying the new API with Oculus Quest (mostly with Oculus Link, but I tested without Link as well),
    and this function does not return any poits at all for me.
    Since the API is new and I just started using it over the old OculusIntegration etc., I assume I'm missing something on my end.
    What I'm trying is this:

    Code (CSharp):
    1.     public void get_boundary_vertices()
    2.     {
    3.         List<XRInputSubsystem> subsystems = new List<XRInputSubsystem>();
    4.         SubsystemManager.GetInstances<XRInputSubsystem>(subsystems);
    5.  
    6.         // make sure I actually have a subsystem loaded
    7.         if (subsystems.Count > 0)
    8.         {
    9.             // create a List of Vec3 that will be filled with the vertices
    10.             List<Vector3> boundaryPoints = new List<Vector3>();
    11.  
    12.             // if this returns true, then the subsystems supports a boundary and it should have filled our list with them
    13.             if (subsystems[0].TryGetBoundaryPoints(boundaryPoints))
    14.             {
    15.                 foreach (Vector3 pos in boundaryPoints)
    16.                 {
    17.                     // TODO: do something sensible with the points, not this
    18.                     Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), pos, Quaternion.identity);
    19.                 }
    20.             }
    21.         }
    22.     }
    Since I'm chipping in here you might suspect: it does not work ^^ The TryGetBoundaryPoints function returns true, but the list remains empty.
    - The subsystems seems loaded correctly ( when stepping through I do get an "oculus input")
    - it does not matter whether oculus Link is used or not
    - I've tried it with stationary boundary as well as a roomscale boundary setup
    - I thought maybe I need to call Start on the subsystem manually, but that did not do the trick
    - I am using the default 3D pipeline atm
    - other calls to the subsystem (i.e.GetTrackingOriginMode and GetSupportedTrackingOriginModes) return as expected

    I might be missing something obvious, but so far this has brought me no luck.
    The docs are sparse, in classic Unity fashion. ^^ The parameter is not explicitely declared and out param nor ref, so I'm not even sure this is how it is meant to work at this point!?

    I saw another user 'MrNorel' in another forum thread say it worked for him with a slightly other way of getting to the subsystem, but trying that made no difference.
    (this thread: https://forum.unity.com/threads/get-vr-room-scale-bounds-w-native-unity.678289/#post-5366235)

    If anyone has a working version or can tell me where I am going wrong, I would appreciate it :)
     
    Last edited: Mar 6, 2020
    AlinaKutsa, Cazforshort and JoeStrout like this.
  9. StayTalm_Unity

    StayTalm_Unity

    Unity Technologies

    Joined:
    May 3, 2017
    Posts:
    182
    @Enzo-z1 The bool that it returns, returns whether or not boundary points were successfully retrieved. This is important because there could be 0 points, but it can still have successfully got those 0 points, compared to some kind of internal failure to get points at all. The second benefit to this 'return value stating if function was a success, return data as paramters' pattern is that it can help you avoid heap allocations. You can reuse the same List and avoid creating new memory that needs to be almost immediately cleaned up because you specify which list to fill with data. If we returned a list, we couldn't let you supply a location in memory to put the boundary data.

    That function expects a List<Vector3> to be passed in. That list gets filled with boundary points. So you would use it somewhat like this:
    Code (CSharp):
    1. List<XRInputSubsystem> inputSubsystems = new List<XRInputSubsystem>();
    2. SubsystemManager.GetInstances<XRInputSubsystem>(inputSubsystems);
    3. if(inputSubsystems.Count > 0)
    4. {
    5.     List<Vector3> boundary = new List<Vector3>();
    6.     if(inputSubsystems[0].TryGetBoundaryPoints(boundary))
    7.     {
    8.         // boundary is now filled with the current sequence of boundary points
    9.     }
    10. }
     
  10. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,924
    @StayTalm_Unity This doesn't appear to work at all with Quest + 2019.3.3 + v14 + XRPluginManagement/OculusLoader

    I get one XRInputSubsystem (not much info on that object to debug, but I see it's reporting "Floor" mode, as expected), but zero points. I stuck it in Update to isolate any issues with startup/callbacks, and I just get neverendign "Nope, ther'es no boudnary", even when I can see it right in front of me :).
     
  11. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,924
    PS: I dislike the "if( success )" approach to API coding. It gives you no information about what the succes / failure was. If that's going to be in the final release, please could we upgrade to API's with a signature more like:

    Code (CSharp):
    1. void TryThing( List preAllocList, out ErrorObjectOrNull );
    ...or go with the C# practice of throwing an exception on failure. Debugging in the presence of core methods that are returning "false" is a nightmare, especailly on larger projects.
     
    IS_Twyker and glenneroo like this.
  12. miik2

    miik2

    Joined:
    Aug 23, 2018
    Posts:
    5
    This also doesn´t work for me. I work also with Quest, 2019.3.0f6 and the XRPlugin Managment System. I get an empty list .. Do you have any suggestions or is this a known issue?
     
    IS_Twyker and Cazforshort like this.
  13. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,924
    I guess: file a bug, with an empty project that has just one class that demonstrates the problem.

    As far as I can tell, we're doing it right, it's just not working :)
     
    Cazforshort likes this.
  14. koniouchine

    koniouchine

    Joined:
    Mar 3, 2018
    Posts:
    5
    I read a bunch of posts and eventually pieced together the following solution.
    Now I can create an outline of my outer boundary using a some primitives.


    Code (CSharp):
    1. public GameObject wallMarker;
    2. //Check if the boundary is configured
    3. bool configured = OVRManager.boundary.GetConfigured();
    4.         if (configured)
    5.         {
    6.             //Grab all the boundary points. Setting BoundaryType to OuterBoundary is necessary
    7.             Vector3[] boundaryPoints = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.OuterBoundary);
    8.      
    9.              //Generate a bunch of tall thin cubes to mark the outline
    10.             foreach (Vector3 pos in boundaryPoints)
    11.             {    
    12.                 Instantiate(wallMarker, pos, Quaternion.identity);
    13.             }
    14.         }
    Now I just need to figure out how to position the play area so that the created boundary is positioned correctly relative to the starting position of the player.
    If anyone knows how to do that. Feel free to post it.

    Edit: This is using Unity 2019.3.0f1 and building directly to a Quest
     
    glenneroo likes this.
  15. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,924
    That's using a different API though, and will only work for one headset / manufacturer, right?

    i.e. it's not using the universal, cross-platform, API that most of us in this thread were trying to get working (which should work on all headest, from all manufacturers. In theory)
     
    Cazforshort likes this.
  16. koniouchine

    koniouchine

    Joined:
    Mar 3, 2018
    Posts:
    5
    Fair enough

    When I was reading this I was thinking about building to Oculus, so I must have missed the part where this thread was supposed to be device agnostic.
     
  17. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    @StayTalm_Unity same here, no points returned at all with TryGetBoundaryPoints. One subsystem found.
    Unity 2019.3.10f1, XR Plugin Management 3.2.9, Oculus XR Plugin 1.3.3. Oculus Rift S as well as Quest+Link.

    The "old" way of Oculus also does not return any points.
     
    IS_Twyker and Cazforshort like this.
  18. Adrien_Triangles

    Adrien_Triangles

    Joined:
    Feb 4, 2016
    Posts:
    35
    Hello! Does anyone know and is willing to explain how to convert these data from above posts to a Unity Spline ?
    Thanks ! :)
     
  19. stevendimmerse

    stevendimmerse

    Joined:
    Aug 7, 2018
    Posts:
    9
    Having the same issue have to build for the quest every time to test, no boundary data with the quest in link mode
     
    Cazforshort likes this.
  20. Fingerbob

    Fingerbob

    Joined:
    Sep 6, 2014
    Posts:
    24
    Same issue - 2019.3.13f1, XR Plugin Management 3.2.10, Oculus XR plugin 1.3.4.
    no points returned (list count is zero). return value is true (indicating success). XR input subsystem is running. I've also tried polling it every second for the next minute (to see if it kicks into life) - no joy. Nothing fires the boundary changed callback.
     
    Cazforshort likes this.
  21. masai2k

    masai2k

    Joined:
    Mar 2, 2013
    Posts:
    45
    I have the same problem, any news??
     
    IS_Twyker and Cazforshort like this.
  22. Greg-Bassett

    Greg-Bassett

    Joined:
    Jul 28, 2009
    Posts:
    628
    Same here, no point data, any news?
     
    IS_Twyker and Cazforshort like this.
  23. abszisse

    abszisse

    Joined:
    Jul 10, 2019
    Posts:
    2
    Same here. I tried using OVRPlugin.GetBoundaryGeometry2 directly and the portable TryGetBoundaryPoints on Quest. Both sometimes return a list of points or zero points randomly. Since The OVRPlugin is used by Unity behind the XR API internally, I guess this is a problem in the OVRPlugin :-(
     
  24. JPMcWhiskers

    JPMcWhiskers

    Joined:
    Sep 22, 2014
    Posts:
    14
    Hey so, I think most people are having trouble getting boundary points from the quest when debugging with Link enabled. This is frustrating, but there is a bit of a long winded work around.

    You can run the application without link and (go to untrusted sources in the Quest UI and run your application whilst not debugging in Unity), then "TryGetBoundaryPoints" and all of the related methods will work. You can "simply" log the point array to debug and then logcat your device through adb (./adb logcat -s Unity in powershell) and then use the points in your app.

    Where I'm kind of falling down is that my position in relation to those points seems to change when I'm debugging in relation to the boundary I've drawn on the quest. Can someone tell me how I can set the player orientation and position while debugging in Unity so that my copied boundary points will coincide with my current player position?
     
    Cazforshort likes this.
  25. Bunsigi

    Bunsigi

    Joined:
    May 18, 2020
    Posts:
    1

    hey!I love your solution of getting BoundaryPoints, but I don't know how to use XRInputSubsystem.boundaryChanged. Since it's an event not bool so I don't know how to check it. I have searched for a long time but the only useful answer is this forum, could you give some example code for this ?
     
  26. Akura

    Akura

    Joined:
    Jun 28, 2015
    Posts:
    23
    Is there a solution that appeared in the meantime?
     
    IS_Twyker likes this.
  27. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    231
    Good question. Most of the solutions provided reference
    OVRBoundary.BoundaryType.OuterBoundary which as of a few weeks is marked as deprecated by Oculus SDK: "This enum value will not be supported in OpenXR".
     
  28. Dark-Table

    Dark-Table

    Joined:
    Nov 25, 2008
    Posts:
    315
    tenconmar and glenneroo like this.
  29. aleciuf

    aleciuf

    Joined:
    Feb 12, 2017
    Posts:
    7
    Did you find a solution? Same problem here: starting the game with a real position (my physical position) not exactly at the center of the play area (Quest guardian), the boundaries points are not aligned with real guardian boundaries
     
  30. wb4

    wb4

    Joined:
    May 6, 2021
    Posts:
    3
    When the player recenters, the boundary position and rotation change but its geometry stays the same. This still triggers a boundary change event. In your event handler you check if the geometry has changed by determining the transform it would take to go from the new to the old (which you can do by looking at the first two* points of each) and then applying that transform to the new one and seeing if the result corresponds point-for-point with the old one. If it does, then you just apply that same transform to the camera's local** transform's position and forward direction and request a teleport to that place and rotation.

    The user will just see a flicker when they try to recenter.

    * In practice, you should actually look at the first and middle points of each. I've found that limited float precision trips things up if you look at two points that are very close together.

    ** Because the boundary points are relative to the XR rig.
     
    Last edited: Nov 18, 2021
    tenconmar likes this.
  31. wb4

    wb4

    Joined:
    May 6, 2021
    Posts:
    3
    See my reply to koniouchine.
     
  32. Harald-AMF

    Harald-AMF

    Joined:
    Jun 7, 2021
    Posts:
    1
    I am using OpenXR with Unity2020.3.20f1, and TryGetBoundaryPoints works well and returns the 4 corners of the GREEN area defined by SteamVR. However, when entering play mode inside the Vive headset the blue grid follows the BLUE corners, not the green area. Is there another function which returns the user defined blue corners and not the green "squared" version ?

    SteamVR play area.PNG
     
    IS_Twyker likes this.
  33. IS_Twyker

    IS_Twyker

    Joined:
    Sep 6, 2021
    Posts:
    35
    Would also need this. :/

    @StayTalm
    @StayTalm_Unity
     
  34. IS_Twyker

    IS_Twyker

    Joined:
    Sep 6, 2021
    Posts:
    35
    @StayTalm
    @StayTalm_Unity

    Bump. As it's not possible to get the actual boundaries via OpenXR, is there any solution for this?
     
  35. StayTalm

    StayTalm

    Joined:
    Jul 18, 2017
    Posts:
    2
    I don't work at Unity anymore. I left over a year ago.
    I plumbed the boundary API up from the lower level APIs in OpenVR and Oculus.
    I did not implement the OpenXR version.

    I can't get you an answer for this, so I'm pinging someone who still works there. @chris-massie
     
    IS_Twyker likes this.
  36. IS_Twyker

    IS_Twyker

    Joined:
    Sep 6, 2021
    Posts:
    35
    Thanks so much
     
  37. a_rucula_do_mal

    a_rucula_do_mal

    Joined:
    Nov 22, 2015
    Posts:
    3
    Any news on this issue? It totally freezes projects that need passthrough + outer/detailed guardian bounds
     
  38. VRDave_Unity

    VRDave_Unity

    Unity Technologies

    Joined:
    Nov 19, 2021
    Posts:
    260
    Hey everyone, I hope I have an answer here for you. I just tossed this together and tested that it works (with Unity 2020.3.34f) with Quest 2 over Link via Oculus as the OpenXR runtime as well as SteamVR as the OpenXR runtime. If it doesn't work, let us know and we'll keep digging. I think the key here is to wait for the event that the boundary has changed, otherwise the
    TryGetBoundaryPoints
    call always comes back false.

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.XR;
    4. using UnityEngine.XR.Management;
    5.  
    6. public class BoundaryList : MonoBehaviour
    7. {
    8.     void Start()
    9.     {
    10.         var loader = XRGeneralSettings.Instance?.Manager?.activeLoader;
    11.         if (loader == null)
    12.         {
    13.             Debug.LogWarning("Could not get active Loader.");
    14.             return;
    15.         }
    16.  
    17.         var inputSubsystem = loader.GetLoadedSubsystem<XRInputSubsystem>();
    18.         inputSubsystem.boundaryChanged += InputSubsystem_boundaryChanged;
    19.     }
    20.  
    21.     private void InputSubsystem_boundaryChanged(XRInputSubsystem inputSubsystem)
    22.     {
    23.         List<Vector3> boundaryPoints = new List<Vector3>();
    24.         if (inputSubsystem.TryGetBoundaryPoints(boundaryPoints))
    25.         {
    26.             foreach (var point in boundaryPoints)
    27.             {
    28.                 Debug.Log(point);
    29.             }
    30.         }
    31.         else
    32.         {
    33.             Debug.LogWarning($"Could not get Boundary Points for Loader");
    34.         }
    35.     }
    36. }
    37.  
     
    DavidZobrist likes this.
  39. IS_Twyker

    IS_Twyker

    Joined:
    Sep 6, 2021
    Posts:
    35
    The problem is that TryGetBoundaryPoints doesn't return the boundaries, but always just the 4 corner points of the play area.

    Oh, and side from that, without the rotational information of the VR grid compared to the Unity coordinate system where these are coming from, even the play area is semi-useless, I fear. :/

    @VRDave_Unity @vrdave
     
  40. VRDave_Unity

    VRDave_Unity

    Unity Technologies

    Joined:
    Nov 19, 2021
    Posts:
    260
    This is actually not a Unity limitation but an OpenXR spec limitation. The runtimes are supposed to expose and return the play area / stage / reference space to the developers to define the safe, unobstructed area. The Unity OpenXR plugin simply calls into this API to get the data back. If you want the exact boundary positions, you'll probably have to use the vendor-specific plugin/API.

    In terms of rotation, the boundary points should be based on the XR Origin / HMD camera forward direction in your scene setup.

    What is your use-case to using the entire boundary area rather than the designated 'safe zone'?
     
  41. BuzzJive

    BuzzJive

    Joined:
    Mar 6, 2014
    Posts:
    75
    It's important to note that this will NOT work if you've installed the Oculus Integration plugin from the asset store or asset packages unless you choose to keep the plugin in Legacy mode (which is not the default). Also, TryGetBoundaryPoints returns no actual points if you are using Unity 2021 and upgrade to Oculus 2.x or 3.x packages in the Package Manager. Oculus 1.12.1 seems to work in Unity 2020 and 2021 (though you may have to manually downgrade on 2021). Those are my findings over the past few days of upgrade processes - and just using a Quest 2 - no Airlink or Rift testing.
     
  42. jcarff

    jcarff

    Joined:
    Feb 8, 2017
    Posts:
    3
    does anyone know why TryGetBoundaryPoints doesn't return actual points if you are using Unity 2021. I just upgraded recently on a project that relies heavily on getting the users boundary points so that I could use a few new 2021 features and took me a while to realize why things were not working anymore.
     
  43. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    231
    TryGetBoundaryPoints should work in Builds but not in the Editor. My hack around this is to run a build, dump this Vector3 list to a log file and then use these values inside an #if UNITY_EDITOR code block.

    There have also been requests on Oculus forums to fix this since at least 2021 (the year, not Unity version).
     
  44. jcarff

    jcarff

    Joined:
    Feb 8, 2017
    Posts:
    3
    My problem is that is still does not work on builds. i have made the simplest test case where i have a script that is occasionally requesting boundary points and displaying that number of points on a canvas in VR, if i am in 2020 this works fine and I get over 200 points in my list. as soon as i update to 2021, my list size is 0 even on deployed builds.
     
  45. BuzzJive

    BuzzJive

    Joined:
    Mar 6, 2014
    Posts:
    75
    I could only get TryGetBoundaryPoints to work when using Oculus Plugin 1.12.1 (which is what Unity 2020 uses). Oculus 2.x and 3.x give me nothing - and those are what Unity 2021 defaults to. You have to force a downgrade in the packages manifest. I've since started using OpenXR instead of Oculus, which gives me access to OVRManager.boundary.GetGeometry, which doesn't give as much detail as TryGetBoundaryPoints but you can get the basic rectangle of the play space.
     
  46. IS_Twyker

    IS_Twyker

    Joined:
    Sep 6, 2021
    Posts:
    35
    @VRDave_Unity @vrdave
    We need to implement our own chaperone system/boundary visualization and obviously would like to be hardware agnostic, hence the use of OpenXR.
    It would make sense to be able to access the exact points that the user defined beforehand as the method is literally called TryGetBOUNDARYPOINTS not TryGetPLAYAREA, right? :/
     
  47. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    858
    [EDITED]

    For those who want exact Guardian bounds drawn by the user on Meta Quest:

    At the time of writing (Unity 2021.3 and Oculus Integration 43.0), you need to use OVRManager.boundary.GetGeometry( OVRBoundary.BoundaryType.OuterBoundary ). And for that to work you need to switch to "Legacy LibOVR+VRAPI" in the top menu: Oculus -> Tools -> OVR Utilities Plugin.
     
    Last edited: Oct 2, 2022
  48. tp_up

    tp_up

    Joined:
    Oct 5, 2021
    Posts:
    1
    as legacy mode does not support passthorugh, its a bit sad there is no working version where we can have both the precise guardian (more than 4 corners), and passthough mode.
    unless i am completely missing an option, this does not seem currently possible?

    having both these features, working on the quest 2, seems to be impossible...
     
  49. rosssssss

    rosssssss

    Joined:
    Jan 27, 2017
    Posts:
    70
    This is a bit rubbish. We really need full boundary information and passthrough working -
    if the user has an L-shaped space then we want to decide where the center of play is based on where they are when they start the experience - currently the PlayArea is decided by the algorithm and could be at the other end of the boundary.... and we have no way of knowing what space is available where they are currently standing even though they are within their drawn boundary.