Create babylon instance with a function

hello, i want to create babylon js instance with a simple function and i get :
index.php:1 Uncaught (in promise) engine should not be null.
how to do this?

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <title>Babylon.js sample code</title>

        <!-- Babylon.js -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
        <script src="https://preview.babylonjs.com/ammo.js"></script>
        <script src="https://preview.babylonjs.com/cannon.js"></script>
        <script src="https://preview.babylonjs.com/Oimo.js"></script>
        <script src="https://preview.babylonjs.com/earcut.min.js"></script>
        <script src="https://preview.babylonjs.com/babylon.js"></script>
        <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
        <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
        <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>

        <style>
            html, body {
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #renderCanvas {
                width: 100%;
                height: 100%;
                touch-action: none;
            }
        </style>
    </head>
<body>
    <canvas id="renderCanvas"></canvas>
    <script>
    
 
    function create_babylon(){
        
             var canvas = document.getElementById("renderCanvas");

        var engine = null;
        var scene = null;
        var sceneToRender = null;
        var createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true,  disableWebGL2Support: false}); };
        const createScene = () => {
    const scene = new BABYLON.Scene(engine);

    const camera = new BABYLON.ArcRotateCamera("Camera", 3 * Math.PI / 4, Math.PI / 4, 4, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));

    const box = BABYLON.MeshBuilder.CreateBox("box", {height: 1, width: 0.75, depth: 0.25});

    return scene;

};;
                window.initFunction = async function() {
                    
                    
                    var asyncEngineCreation = async function() {
                        try {
                        return createDefaultEngine();
                        } catch(e) {
                        console.log("the available createEngine function failed. Creating the default engine instead");
                        return createDefaultEngine();
                        }
                    }

                    window.engine = await asyncEngineCreation();
        if (!engine) throw 'engine should not be null.';
        window.scene = createScene();};
        initFunction().then(() => {sceneToRender = scene        
            engine.runRenderLoop(function () {
                if (sceneToRender && sceneToRender.activeCamera) {
                    sceneToRender.render();
                }
            });
        });

        // Resize
        window.addEventListener("resize", function () {
            engine.resize();
        });
        
    }
    
       create_babylon();
    
   
    </script>
</body>
</html>

You are nulling the engine, so the engine is null. You made some changes to the code. In this case you would need to create the engine yourself using the function you have added (createDefaultEngine). Otherwise you are passing null to the scene.

Hello @Paul_Ksi just checking in if your question was answered :slight_smile:

I have same problem. This is my code, but I have this error:

Cannot read properties of null (reading ‘runRenderLoop’)
at viewerjs_init.js:110:14
(anonimo) @ viewerjs_init.js:11

properties of null (reading ‘resize’)
at viewerjs_init.js:119:14
(anonimo) @ viewerjs_init.js:11

my code

function setupCameraForCollisions(camera) {
	camera.checkCollisions = true;
	camera.applyGravity = true;
	camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);
}

function start3dview(url3d) {
	var canvas = document.getElementById("renderCanvas");

	var startRenderLoop = function (engine, canvas) {
		engine.runRenderLoop(function () {
			if (sceneToRender && sceneToRender.activeCamera) {
				sceneToRender.render();
			}
		});
	}

	var engine = null;
	var scene = null;
	var sceneToRender = null;
	var createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true,  disableWebGL2Support: false}); };
	var createScene = async function () {
		var scene = new BABYLON.Scene(engine);
		scene.gravity = new BABYLON.Vector3(0, -0.5, 0);
		scene.collisionsEnabled = true;
		scene.clearColor = new BABYLON.Color4(0.5, 0.5, 0.5, 0.6); //Gray
		//scene.clearColor = new BABYLON.Color4(0.9, 0.9, 0.1, 0.6); //yellow
		//scene.createDefaultEnvironment();
		//scene.createGround = true;
		//scene.skyboxSize = false;

		//Create a Camera
		const alpha =  Math.PI/2; //rotazione dell'oggetto (target)
		const beta = Math.PI/2;
		const radius = 20; //distanza dall'oggetto (target)
		const target = new BABYLON.Vector3(0, 7, 0);
		
		//const blueMaterial = new BABYLON.StandardMaterial('blueMat', scene);
		//blueMaterial.emissiveColor = new BABYLON.Color3(1, 0.9, 0);
	
		//Pavimento (Ground)
		//const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 70, height: 70}, scene);
		//ground.position.y = 0;  
		//ground.checkCollisions = true;
		//ground.material = blueMaterial;
		
		//Camera
		const camera = new BABYLON.ArcRotateCamera("camera", alpha, beta, radius, target, scene);
		camera.useAutoRotationBehavior = true;
		camera.autoRotationBehavior.idleRotationSpeed = 0.1;
		camera.autoRotationBehavior.idleRotationSpinupTime = 0;
		camera.autoRotationBehavior.zoomStopsAnimation = false;
		
		//const camera = new BABYLON.FreeCamera("camera", new BABYLON.Vector3(alpha, beta, radius), scene);
		//camera.setTarget(target);
		
		camera.attachControl(canvas, true);

		setupCameraForCollisions(camera);
					
		//Light
		const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 3, 1), scene);
		light.diffuse = new BABYLON.Color3(1, 1, 1);
		light.specular = new BABYLON.Color3(0, 0, 0);
		//light.groundColor = new BABYLON.Color3(1, 1, 0);
		
		// Append glTF model to scene.
		BABYLON.SceneLoader.Append("", url3d, scene, function (scene) {
			
			// Create a default arc rotate camera and light.
			//scene.createDefaultCameraOrLight(true, true, true);
		
			// The default camera looks at the back of the asset.
			// Rotate the camera by 180 degrees to the front of the asset.
			//scene.activeCamera.alpha += Math.PI;
		});
		
		
		// XR
		const xrHelper = await scene.createDefaultXRExperienceAsync({
			//floorMeshes: [ground],
			disableTeleportation: true,
		});
		
		//Movimento
		const featureManager = xrHelper.baseExperience.featuresManager;
		featureManager.enableFeature(BABYLON.WebXRFeatureName.MOVEMENT, 'latest', {
			xrInput: xrHelper.input,					
		});
	
		return scene;
	};
	window.initFunction = async function () {

      var asyncEngineCreation = function () {
        try {
          return createDefaultEngine()
        } catch (e) {
          console.log('the available createEngine function failed. Creating the default engine instead')
          return createDefaultEngine()
        }
      }

      window.engine = asyncEngineCreation()
      if (!window.engine) throw 'engine should not be null.'
      window.scene = createScene(window.engine)
    }
    initFunction().then(() => {
      sceneToRender = scene
      engine.runRenderLoop(function () {
        if (sceneToRender && sceneToRender.activeCamera) {
          sceneToRender.render()
        }
      })
    })

    // Resize
    window.addEventListener('resize', function () {
      engine.resize()
    })
}

Are you actually calling the engine creation function? :slight_smile: