Babylon.js Reactjs Object import Problem

Hello everyone,
I would like to ask you a point that makes me crazy. I currently working on a React app that contains Babylon.js framework. I built my app depending on following documentation.
React and Babylonjs Documentation

Yet, my problem is that I couldn’t achieve importing objects into my scene. Without React, I was doing it with ‘Babylon.SceneLoader.Append’ function. Here is the trial that I have done so far. The code is inside a .js file which is run by app.js.

import React, { Component } from 'react';

import * as BABYLON from 'babylonjs';

import 'babylonjs-loaders';

import "@babylonjs/loaders/OBJ";

import "@babylonjs/loaders/OBJ";

import { Engine, Scene } from '@babylonjs/core';

//import * as GUI from "babylonjs-gui";

import BabylonScene from './Babylon.jsx'; // import the component above linking to file we just created.

export default class Viewer extends Component<{}, {}> {

    onSceneMount = (e: SceneEventArgs) => {

        const { canvas, scene, engine } = e;

        const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);

        camera.setTarget(BABYLON.Vector3.Zero());

        camera.attachControl(canvas, true);

        const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

        light.intensity = 0.7;

        BABYLON.SceneLoader.Append("/assets/", 'Chair.obj', scene, function (scene) { });

        engine.runRenderLoop(() => {

            if (scene) {

                scene.render();

            }

        });

    }

    render() {

        return (

            // <div>

            <BabylonScene onSceneMount={this.onSceneMount} />

            // </div>

        )

    }

}

my app contains Amplify authentication as well. In addition, the application works perfectly with “BABYLON.MeshBuilder.CreateBox” function. The only problem is the object import. I hope you can help me. Thanks in advance.

1 Like

Hi Nevzat_Anil_Talaym,

Welcome to Babylon! Can you provide some more information about the problem you’re experiencing? A Playground reproducing the issue would be ideal, but a call stack or an error message or something could also help us understand what’s going on. Thanks!

Looks like you mixed the es6 import with the original npm. If you make a public repo I can send you a fix.

Thanks for your interest. I have uploaded my codes into github repository. If you check the Viewer.js file , you will see the code that I have shared earlier. If you run the repository on your local computer, everything works prefect except the import command. The mainBabylon.js page is in the Viewer.js file.

You may want to focus on following line in Viewer.js
BABYLON.SceneLoader.Append("", ‘Chair.obj’, scene, function (scene) { });

Repository Link: React-Trial/Viewer.js at master · NevzatTalay/React-Trial · GitHub

If you need any further information please contact me.

thanks for your interest. Here is the repository of my project.


Thank you very much.

That was super close. The main thing you were missing was the root url for the loader. You can see this from the console log errors (the OBJLoaders couldn’t load your index.html, which is what is served when there is no physical file), but you can also see it from the network tab. Those are in developer tools. Anyway, if you update your Viewer.js to this you should be good:

import React, { Component } from 'react';
import '@babylonjs/loaders'; // import for side-effects (loads OBJ loader automatically)

import { ArcRotateCamera, HemisphericLight, Vector3, SceneLoader } from '@babylonjs/core';
import BabylonScene from './Babylon.jsx'; // import the component above linking to file we just created.
export default class Viewer extends Component {
onSceneMount = (e) => {
    const { canvas, scene, engine } = e;
    const camera = new ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 4, 75, new Vector3(0, 75, 0), scene);
    camera.attachControl(canvas, true);
    const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene);
    light.intensity = 0.7;


    // You missed the rootUrl only (see /public/assets/) and /public is your ROOT '/'!
    SceneLoader.Append("/assets/", 'Chair.obj', scene, function (scene) { });

    engine.runRenderLoop(() => {

        if (scene) {
            scene.render();
        }
    });
}

render() {
    return (
        <BabylonScene onSceneMount={this.onSceneMount} />
    )
}
}

Then you just need to remove the imports for babylonjs and babylonjs-loaders. And add @babylonjs/loaders. I would recommend an editor like VSCode - it would have shown you also that you had errors in your file (You had TypeScript typings in a javascript file).

I noticed also that you imported react-babylonjs in your project already. If you want to do a declarative version equivalent then you can remove your babylon.jsx and do this instead in Viewer:

import React, { Component } from 'react';
import { Scene, Engine, Model } from 'react-babylonjs'
import { Vector3 } from '@babylonjs/core'

export default class Viewer extends Component {
    render() {
        return (
            <Engine antialias adaptToDeviceRatio width={window.innerWidth} height={window.innerHeight}>
                <Scene>
                    <arcRotateCamera name='camera1' alpha={Math.PI / 2} beta={Math.PI / 4} radius={75.0} target={new Vector3(0, 75, 0)} />
                    <hemisphericLight name='light1' intensity={0.7} direction={Vector3.Up()} />
                    <Model rootUrl={`/assets/`} sceneFilename='chair.obj' />
                </Scene>
            </Engine>
        )
    }
}

So, that’s another way since you have already imported the react-babylonjs NPM, but otherwise you can remove that NPM if you want to do it how you have it before :slight_smile: If you have more questions just @mention me. Cheers.

3 Likes