No way to tell not on anXR Device, promise fail code never called

I want a scene to run either on a desktop or XR & be able to know the difference. There is no real way to check whether you are on an XR device, AFAIK, so I am just creating a default experience, and putting code in the failed section of the promise, Babylon.js Playground

const xr = BABYLON.WebXRDefaultExperience.CreateAsync(scene).then((defaultExperience) => { 
        xrHelper = defaultExperience.baseExperience;
     }, (error) => {
        alert('This is an alert, which never gets called on a desktop, Why??');
    });

In the PG, the alert box is never executed. I just get 2 (why not just one?) messages in the console.

Now this might not a bug. I HATE promises, so I avoid them at all costs. I could be just doing this wrong.

pinging @RaananW

No way to avoid them here, i’m afraid :slight_smile:
You should learn to live with them, the entire XR API is based on them.

To check if a device is XR ready you can check if a specific session is available (just like we are doing before presenting the GUI button). There is a static function in the session manager :slight_smile:
Babylon.js/webXRSessionManager.ts at master · BabylonJS/Babylon.js (github.com)

It is a promise that will resolve with true if the session is supprted (for example immersive-vr or immersive-ar)

1 Like

While you solved my goal, not sure why that test did not work, & neither did the .catch variation.

On the plus side, the direct test method does not even require an engine or scene, so you can even change how those are created / optioned once you know.

let canvas;
let engine;
let scene;

let isXRCapable;

BABYLON.WebXRSessionManager.IsSessionSupportedAsync("immersive-vr").then((result) =>{
    isXRCapable = result;
    begin();
});

function begin() {
    canvas = document.getElementById("renderCanvas");
    engine = new BABYLON.Engine(canvas, true);
    scene = new BABYLON.Scene(engine);
    . . .
}

Epilogue: Might there be some other test which returns a string array of the modes available, length 0 if neither. Kind of an enhancement request. I know I could do this myself, but seems like more than me would like this.

Use cases:

  • You have a scene which primarily works on AR, but you want to also have some functionality if just VR.
  • There exists AR devices which do not do VR as well. You have a scene which primarily works on VR, still wish it to do something on an AR only device.

WebXR is very passive in that sense. it does not provide you with a list of available session modes, but checks if the session mode you want is available. So the function will need to iterate all known session modes (not a lot TBH) and return the result. This would be a simplified version:

const results = await Promise.all(['immersive-vr', 'immersive-ar'].map(key => BABYLON.WebXRSessionManager.IsSessionSupportedAsync(key)));

I am not entirely sure if i want to include something like this in the framework, but let me think about it a little more :slight_smile: