-
Notifications
You must be signed in to change notification settings - Fork 0
Creating a scene from scratch
The process for creating your own scenes is outlined as follows:
- Clone the starter template
- Create your scene in Blender
- Export the scene meshes with the Scene Slicer plugin
- Export the scene colliders with the Cannon Collider plugin
- Configure the Infinity Engine to use your scene
- See [Infinity Engine Configuration]
We will use this repo (infinity-engine-sdk7-template
) as a starter scene to get you off the ground faster.
- Clone the repository
- Open the repository in VSCode
- Place your non-deployable assets - such as .blend files - in the
assets
folder - Create the folder
models/myFirstScene
- Ensure you have installed Blender, install plugins blender-dcltk-scene-slicer, and blender-dcltk-cannon-colliders
- Follow steps for blender-dcltk-scene-slicer. Export your sliced models into the scene folder
models/myFirstScene
. - Follow steps for blender-dcltk-cannon-colliders. Export your
colliders.json
into scene foldermodels/myFirstScene
. - Before you continue verify your exported folder
models/myFirstScene
looks similar to this format:
//models/myFirstScene
├──tex (textures here)
| └──*.png
├──tile_0_1_0.bin
├──tile_0_1_0.gltf
├──tile_0_1_1.gltf
├──tile_0_1_1.gltf
├──...
├──tileset.json
└──colliders.json
Ensure that it:
- Has a
tileset.json
file - Has many sliced models
tile_*
- Has a
tex
folder for any model textures - Has a
colliders.json
file
Inside the src/myFirstScene/getting-started.ts#createSceneConfig()
method. Adjust as nessesary:
NOTE: All code for
src/myFirstScene/getting-started.ts#initMyFirstScene()
is already there just commented out.
-
Remove the return statement to activate code:
//src/myFirstScene/getting-started#initMyFirstScene() export function initMyFirstScene(){ //DISABLED FOR NOW //REMOVE THIS ONE TO ACTIVATE THE BELOW CODE return; //<==== REMOVE THIS LINE TO ACTIVATE THE BELOW CODE
-
Import your collider and tileset at the top of file:
Inside the
src/myFirstScene/getting-started.ts#createSceneConfig()
method. Adjust as nessesary:NOTE: All code for
src/myFirstScene/getting-started.ts#initMyFirstScene()
is already there just commented out. You can uncomment or copy paste what is here into it//src/myFirstScene/getting-started import colliderJSON from '../models/myFirstScene/colliders.json' import tilesetJSON from '../models/myFirstScene/tileset.json'
-
Define scene configuration:
See full description of each option here: Infinity Engine Configuration
Inside the
src/myFirstScene/getting-started.ts#createSceneConfig()
method. Adjust as nessesary:NOTE: All code for
src/myFirstScene/getting-started.ts#initMyFirstScene()
is already there just commented out. You can uncomment or copy paste what is here into it//src/myFirstScene/getting-started#createSceneConfig() function createSceneConfig():SceneConfig{ let conf:SceneConfig ={
Main things to update here are
// CORRECT THE PATH TO MATCH WHERE YOU EXPORTED THE COLLIDER JSON import colliderJSON from '../../models/stom-skatepark-8x8x30/colliders.json'
// CORRECT THE PATH TO MATCH WHERE YOU EXPORTED THE TILESET import tilesetJSON from '../../models/stom-skatepark-8x8x30/tileset.json'
grid: { tileSetConf: { // CORRECT THE PATH TO MATCH WHERE YOU EXPORTED THE TILESET // MUST MATCH FOLDER for generated files from scene-slicer modelFolder: "models/stom-skatepark-8x8x30/", //<== CORRECT THE PATH TO MATCH WHERE YOU EXPORTED MODELS ...
-
Create a Basic Scene:
Inside the
src/myFirstScene/getting-started#initMyFirstScene()
//src/myFirstScene/getting-started#initMyFirstScene() const MY_SCENE_CONF:SceneConfig = createSceneConfig() //turn off any current active scene if(REGISTRY.SCENE_MGR._activeScene){ REGISTRY.SCENE_MGR._activeScene.destroy() } //create a new scene const myScene = new BaseScene(REGISTRY.SCENE_MGR.generateSceneId(),"myScene") myScene.sceneConfig = MY_SCENE_CONF //init the scene myScene.init() //register this scene as the active scene REGISTRY.SCENE_MGR._activeScene = myScene // move player to center of your scene myScene.moveVehicleToDefaultSpawn()
-
Start Scene and Test:
Open the Decentraland Editor tab, and press Run Scene
Alternatively, you can use the command line. Inside this scene root directory run:
npm install npm run start
Following the steps above you should have a fully working Infinity Engine Scene. From here you may want place more interactable entities in specific spots, such as doors, NPCs, etc. Here are the basic to do that.
Inside the src/myFirstScene/getting-started#addAdditionalNonPhysicsEntities()
//src/myFirstScene/getting-started#addAdditionalNonPhysicsEntities()
//define a _scene object to act as the parent of any of your interactive objects
//this will help performance by reducing number of entities the movesWithWorldSystem has to track
const _myNonPhysicsScene = engine.addEntity()
MovesWithWorld.create(_myNonPhysicsScene, { id: "_myNonPhysicsScene" })
Transform.createOrReplace(_myNonPhysicsScene, {
//scale: Vector3.create(6,120,6),
})
//for debugging will assign it a material to see where it is in the world
Material.setPbrMaterial(_myNonPhysicsScene, {
albedoColor: Color4.Black(),
specularIntensity: 0,
metallic: 0,
roughness: 1
})
//make it a box
MeshRenderer.setBox(_myNonPhysicsScene)
Next we will add two cubes at world origin and at a specific place in the scene. See 'Ways to determine position' for how you can position entities manually
//src/myFirstScene/getting-started#addAdditionalNonPhysicsEntities()
//some cleverness to allow making it the parent or not to the other entities below
const parentIt = _myNonPhysicsScene
//create a demo cube to be moved with the world
const testCubeEntOrigin = engine.addEntity()
const testCubeEntOriginPos = Vector3.create(0, 0, 0)
Material.setPbrMaterial(testCubeEntOrigin, {
albedoColor: Color4.Green(),
specularIntensity: 0,
metallic: 0,
roughness: 1
})
MeshRenderer.setBox(testCubeEntOrigin)
Transform.createOrReplace(testCubeEntOrigin, {
//for testing - make it very tall for easy finding
scale: Vector3.create(1, 120, 1),
position: !parentIt ? Vector3.Zero() : testCubeEntOriginPos,
parent: parentIt
})
if (!parentIt) { //if not parented to _myNonPhysicsScene, must add move with world
MovesWithWorld.create(testCubeEntOrigin,{
id: "testCubeEntOrigin",
position: testCubeEntOriginPos
})
}
//create a demo cube to be moved with the world
const testCubeEntPositioned = engine.addEntity()
//setting position, position can inferred from your blender base scene
//or use the debug UI to get the player position standing near where you want it to be placed
const testCubeEntPositionedPos = Vector3.create(25, 5, 65)
Material.setPbrMaterial(testCubeEntPositioned, {
albedoColor: Color4.White(),
specularIntensity: 0,
metallic: 0,
roughness: 1
})
MeshRenderer.setBox(testCubeEntPositioned)
Transform.createOrReplace(testCubeEntPositioned, {
//for testing - make it very tall for easy finding
scale: Vector3.create(3, 120, 3),
position: !parentIt ? Vector3.Zero() : testCubeEntPositionedPos,
parent: parentIt
})
if (!parentIt) { //if not parented to _myNonPhysicsScene, must add move with world
MovesWithWorld.create(testCubeEntPositioned, {
id: "testCubeEntPositioned",
position: testCubeEntPositionedPos
})
}
This will initialize everything the Infinity Engine scene loaded
myScene.init()
This will unload everything the Infinity Engine scene loaded
myScene.destroy()