# Create function to start babylon

**URL:** <https://forum.babylonjs.com/t/create-function-to-start-babylon/39996>\
**Category:** Questions\
**Created:** [April 19, 2023, 9:23am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996 "2023-04-19T09:23:58Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Luca\_Scida](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/luca_scida/32/30906_2.png) [@Luca\_Scida](https://forum.babylonjs.com/u/Luca_Scida)\
**Post date:** [April 19, 2023, 9:23am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/1 "2023-04-19T09:23:58Z")

</div>

I have same problem with ‘engine is null’ when I want to start babylon from function.

This is my code and 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

```auto
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 = 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.';
		startRenderLoop(engine, canvas);
		window.scene = createScene();
	};
	
	initFunction().then(() => {scene.then(returnedScene => { sceneToRender = returnedScene; });
						
	});

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

```

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [April 19, 2023, 11:29am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/2 "2023-04-19T11:29:28Z")

</div>

I’ve already answered you in another thread 🙃 but are you calling the engine creation function?

---

<div class="post-metadata">

**Author:** ![Luca\_Scida](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/luca_scida/32/30906_2.png) [@Luca\_Scida](https://forum.babylonjs.com/u/Luca_Scida)\
**Post date:** [April 19, 2023, 11:42am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/3 "2023-04-19T11:42:43Z")

</div>

what do you mean exactly?

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [April 19, 2023, 11:47am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/4 "2023-04-19T11:47:27Z")

</div>

The `createDefaultEngine` function. I see that it is being called in `initFunction`, but it’s async meaning the engine won’t be created immediately. So the engine can be null during the engine.resize call. I recommend checking this web app template which is simpler and doesn’t have async stuff that messes up timing: [Getting Started - Chapter 1 - Setup Your First Web App | Babylon.js Documentation (babylonjs.com)](https://doc.babylonjs.com/features/introductionToFeatures/chap1/first_app)

---

<div class="post-metadata">

**Author:** ![Luca\_Scida](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/luca_scida/32/30906_2.png) [@Luca\_Scida](https://forum.babylonjs.com/u/Luca_Scida)\
**Post date:** [April 19, 2023, 2:56pm UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/5 "2023-04-19T14:56:36Z")

</div>

I need async for this:

```auto
await scene.createDefaultXRExperienceAsync

```

---

<div class="post-metadata">

**Author:** ![Luca\_Scida](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/luca_scida/32/30906_2.png) [@Luca\_Scida](https://forum.babylonjs.com/u/Luca_Scida)\
**Post date:** [April 19, 2023, 3:14pm UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/6 "2023-04-19T15:14:41Z")

</div>

I change without async, but I have error on  
window.initFunction @ viewerjs\_init.js:103  
‘engine should not be null’

My new code

```auto
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 = 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 = 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 = 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 (!engine) throw 'engine should not be null.';
		startRenderLoop(engine, canvas);
		window.scene = createScene();
	};
	
	initFunction().then(() => {scene.then(returnedScene => { sceneToRender = returnedScene; });
						
	});

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

```

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [April 19, 2023, 4:44pm UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/7 "2023-04-19T16:44:41Z")

</div>

You still need to check if engine exists before calling engine.resize.

---

<div class="post-metadata">

**Author:** ![Luca\_Scida](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/luca_scida/32/30906_2.png) [@Luca\_Scida](https://forum.babylonjs.com/u/Luca_Scida)\
**Post date:** [April 20, 2023, 8:46am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/8 "2023-04-20T08:46:24Z")

</div>

This code it’s working:

```auto
<script>
	async function start3dview(url3d) {
		const canvas = document.getElementById("renderCanvas"); // Get the canvas element
		const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

		var createScene = async function (url3d) {
			var scene = new BABYLON.Scene(engine);
			
			//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 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;		
			camera.attachControl(canvas, true);

			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);

			// 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;
		};

		const scene = await createScene(url3d); //Call the createScene function

		// Register a render loop to repeatedly render the scene
		engine.runRenderLoop(function () {
			scene.render();
		});

		// Watch for browser/canvas resize events
		window.addEventListener("resize", function () {
			engine.resize();
		});
	}
	
	start3dview("marino.glb");
    </script>

```

---

<div class="post-metadata">

**Author:** ![carolhmj](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/carolhmj/32/25918_2.png) [@carolhmj](https://forum.babylonjs.com/u/carolhmj)\
**Post date:** [April 20, 2023, 11:45am UTC](https://forum.babylonjs.com/t/create-function-to-start-babylon/39996/9 "2023-04-20T11:45:20Z")

</div>

Yep because you only add the resize event listener AFTER the engine is created 🙂
