Await xr.baseExperience.enterXRAsync doesn't return on Android device

Hello!
I’m very new to React Native (and JS in general), so I apologize in advance

I’m trying to launch a simple XR(AR) session on my Samsung Galaxy S21 phone.
I have react native and the babylon dependencies installed/

EDIT: A few notes about how I differed from the instruction to install babylon react native.
The Instructions for a fresh project recommend using React native 0.69, but that won’t work properly on my m1 mac, so I used react 71.

But this required me to use @babylonjs/react-native-iosandroid-0-71 - npm (not 64) and my installation command became
pm i @babylonjs/react-native@1.6.4-preview @babylonjs/react-native-iosandroid-0-71 @babylonjs/core @babylonjs/loaders react-native-permissions --legacy-peer-deps. This was needed because 1.6.4 oreview was updated to work with loaders package according to this answer

The scene the code I took from the sample renders fine even with a few small changes

but when I press the Start XR button, nothing happens. I added some debugging logs inside
and only the first one test message 1 is printed.

I think await xr.baseExperience.enterXRAsync is not returning, am I invoking it correctly?

This is my code


import React, {
  FunctionComponent,
  useEffect,
  useCallback,
  useState,
} from 'react';

import {SafeAreaView, View, Button, ViewProps, StatusBar} from 'react-native';

import {EngineView, useEngine} from '@babylonjs/react-native';
import {SceneLoader} from '@babylonjs/core/Loading/sceneLoader';
import {Camera} from '@babylonjs/core/Cameras/camera';
import {ArcRotateCamera} from '@babylonjs/core/Cameras/arcRotateCamera';
import '@babylonjs/loaders/glTF';
import {Scene} from '@babylonjs/core/scene';
import {WebXRSessionManager, WebXRTrackingState} from '@babylonjs/core/XR';
import {LogBox} from 'react-native';


const EngineScreen: FunctionComponent<ViewProps> = (props: ViewProps) => {
  const engine = useEngine();
  const [camera, setCamera] = useState<Camera>();
  const [xrSession, setXrSession] = useState<WebXRSessionManager>();
  const [trackingState, setTrackingState] = useState<WebXRTrackingState>();
  const [scene, setScene] = useState<Scene>();

  const onToggleXr = useCallback(() => {
    (async () => {
      try {
        if (xrSession) {
          await xrSession.exitXRAsync();
        } else if (scene) {
          const xr = await scene.createDefaultXRExperienceAsync({
            disableDefaultUI: true,
            disableTeleportation: true,
          });
          console.log("test message 1");
          const session = await xr.baseExperience.enterXRAsync(
            'immersive-ar',
            'unbounded',
            xr.renderTarget,
          );
          console.log("test message 2");
          setXrSession(session);
          console.log("test message 3");
        }
      } catch (error) {
        console.error("Failed to toggle XR", error);
      }
    })();
  }, [scene, xrSession]);

  useEffect(() => {
    if (engine) {
      const url =
        'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf';
      SceneLoader.LoadAsync(url, undefined, engine).then(loadScene => {
        setScene(loadScene);
        loadScene.createDefaultCameraOrLight(true, undefined, true);
        (loadScene.activeCamera as ArcRotateCamera).alpha += Math.PI;
        (loadScene.activeCamera as ArcRotateCamera).radius = 10;
        setCamera(loadScene.activeCamera!);
      });
    }
  }, [engine]);

  return (
    <>
      <View style={props.style}>
        <Button
          title={xrSession ? 'Stop XR' : 'Start XR'}
          onPress={onToggleXr}
        />
        <View style={{flex: 1}}>
          <EngineView camera={camera} displayFrameRate={true} />
        </View>
      </View>
    </>
  );
};

const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={{flex: 1, backgroundColor: 'white'}}>
        <EngineScreen style={{flex: 1}} />
      </SafeAreaView>
    </>
  );
};

export default App;

If launching for the first time, if i minimize the app and go back in I get

LOG test message 1
LOG [Error: ARCore not installed.]
LOG ARCore not installed.
ERROR Failed to toggle XR [Error: ARCore not installed.]

cc @BabylonNative to help on this one :slight_smile: @ryantrem might also have an idea.

SDK Downloads | ARCore | Google for Developers
I’m not sure if this can solve your problem

To try to narrow things down, have you tried running the Playground app in the BabylonReactNative repo? Do you get the same error?

Also did you include ARCore in your AndroidManifest.xml (something like )?

hi, thanks for all the help.

The error about ARCore not being installed it appears was a little misleading, the problem was that I had downloaded a different version of react-native-permissions and that did not work right.

Using the versions from the sample app worked fine and I am able to launch it, Thanks everyone

2 Likes