Boundaryless
Updated: Nov 15, 2024
While the boundary is an important safety system required for fully immersive apps, it can unnecessarily interrupt the user experience when in a mixed reality experience. Boundaryless and Boundary API provide a mechanism to disable the boundary in mixed reality experiences.
This document details how to implement:
- Boundaryless apps to disable the boundary for an entire experience
- Boundary API for Contextual-Boundaryless apps, allowing your app to operate without a boundary for some or all of an experience.
Boundaryless apps disable the boundary for the entirety of the experience and must not have any immersive experiences. Developers must ensure that it is safe to disable the boundary for the entirety of the app experience.
To make an app boundaryless, add the following entry to the app’s AndroidManifest.xml file:
<uses-feature
android:name="com.oculus.feature.BOUNDARYLESS_APP"
android:required="true"/>
Contextual Boundaryless Implementation
You can access the boundary API through Blueprint and code. Accessing the boundary visibility API requires enabling support in the Meta XR settings within the editor.
Go to Project Settings > Meta XR > Mobile
You can change the default behavior of boundary visibility with the following setting under Project Settings > Meta XR > Mobile
If this setting is enabled then by default the boundary visibility will be suppressed.
Request a new boundary visibility change with the Request Boundary Visibility function. The only parameter is the new visibility you are requesting. The return value is a boolean that is true if the call succeeded or false if not.
You can query the visibility with the Get Requested Boundary Visibility function:
Here is an example of accessing the boundary API via code:
// Retrieving the visibility
EOculusXRBoundaryVisibility outVis;
UOculusXRSceneFunctionLibrary::GetRequestedBoundaryVisibility(WorldContext, outVis);
// Requesting a change to the visibiility
UOculusXRSceneFunctionLibrary::RequestBoundaryVisibility(WorldContext, NewVisibility);
When the boundary visibility changes, an event will fire. You can access and bind to from Blueprints and code.
virtual void ASomeActor::BeginPlay()
{
Super::BeginPlay();
FOculusXRSceneEventDelegates::OculusBoundaryVisibilityChanged.AddUObject(
this,
&ASomeActor::OnBoundaryVisibilityChanged
);
}
void ASomeActor::OnBoundaryVisibilityChanged(
EOculusXRBoundaryVisibility visibility)
{
switch(Location)
{
EOculusXRBoundaryVisibility::NotSuppressed:
// Do something
Break;
EOculusXRBoundaryVisibility::Suppressed:
// Do something
break;
}
}
- The boundary is disabled for boundaryless apps only when they run in headset from a standalone APK. The boundary is not disabled when boundaryless apps run over PC/Link, as
AndroidManifest.xml
has no effect. - The Boundaryless and Boundary API Contextual-boundaryless implementations are mutually exclusive and OS version gated.
- Boundaryless and Contextual-boundaryless only support 6DOF apps. 3DOF apps will not be boundaryless or contextual-boundaryless.
- When apps using the Boundary API ask for the boundary to be suppressed, the system will first verify whether a Passthrough layer is currently active before suppressing the boundary.
- Apps should not rely on the Stage tracking space which only disables the system recentering under certain boundary types. See the next section for how to achieve world-locked contents for boundaryless use case.
Stage tracking space is ill-defined for boundaryless use case, since the user may not have defined any boundary, or may have defined multiple boundaries and move across those boundaries. If Stage tracking space is used for world-locked contents, they may teleport to an unexpected location as the user moves around or recenters their view, resulting in a poor user experience.
Rather than relying on Stage coordinates, you will need to either use
MR Utility Kit World lockingor your app will need to create a spatial anchor either on launch or before entering any world-locked content areas. You can then align your coordinate system to that anchor every frame.