diff --git a/pr-preview/pr-562/examples-engine-scene.html b/pr-preview/pr-562/examples-engine-scene.html index 4a4e3b7ff..f932f941f 100644 --- a/pr-preview/pr-562/examples-engine-scene.html +++ b/pr-preview/pr-562/examples-engine-scene.html @@ -49,7 +49,7 @@
Using the Scene plugin.
-This example shows how the Scene plugin can be used to spawn a scene from an asset.
The plugin function is included from the engine/
cubos.addPlugin(scenePlugin);
Let's start by taking a look at a scene file.
{ +This example shows how the Scene plugin can be used to create scene assets and spawn them on the world.
The plugin function is included from the engine/
scene/ plugin.hpp header. cubos.addPlugin(scenePlugin);Let's start by taking a look at a scene file.
{ "imports": {}, "entities": { "root": { @@ -60,7 +60,7 @@"parent": "root" } } -}
A scene file has two parts: the
imports
and theentities
. Each entity is a list of components, with their values set. So in this file we have two entities, one namedroot
and the other namedchild
.root
has a single component,num
, with a value of 1.child
has two components, aparent
and anum
. In this sample,num
is used so we can later identify the entities.Let's look at a different scene file now, to talk about
imports
, which is the way we can put subscenes within other scenes.{ +}Scene files are JSON files with the extension
.cubos
. They must have two fields:imports
andentities
. Theentities
field is an object where each field identifies and describes the components of an entity. In this scene we have two entities,root
andchild
.root
has a single component,num
, with a value of 1.child
has two components, aparent
and anum
. In this sample,num
is used so we can later identify the entities.Let's look at a different scene file now, this time with
imports
. Imports allows us to instantiate scenes within other scenes.{ "imports": { "sub1": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f", "sub2": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f" @@ -76,26 +76,11 @@"parent": "main" } } -}
This file imports the asset with id
cd007ba2-ee0d-44fd-bf36-85c829dbe66f
, which is the scene we looked at in the previous file. It gives this scene the deisgnation ofsub1
. It then imports the very same scene again, but this time with the namesub2
instead. This allows us to have two instances of the same subscene.Under
entities
, we can reference these labels to change some particular values of the subscenes. For example, by referencingsub1.root
we are making local changes to theroot
entity of that instance of the subscene. The result of the changes we make to bothsub1.root
andsub2.root
is that the parent of these entities will be set to be themain
entity.Now that we have our scene file, let's get CUBOS. to load it. The first thing we're going to need is a reference to the scene asset. For the purposes of this sample we can simply use an hardcoded reference to the asset.
static const Asset<Scene> SceneAsset = AnyAsset("f0d86ba8-5f34-440f-a180-d9d12c8e8b91");Then we'll need a system that spawns that scene. To do this we simply get the Scene object from the asset, and then spawn its entities.
commands.spawn
will create in the world a copy of every entitiy defined in the scene. It won't remove the entities already there, so if you want to close a scene, you'll have to do it yourself.static void spawnScene(Commands commands, Read<Assets> assets) +}This file imports the asset with id
cd007ba2-ee0d-44fd-bf36-85c829dbe66f
, which is the scene we looked at in the previous file, under the namesub1
. It then imports the very same scene again, but this time with the namesub2
instead. This effectively instantiates the entities of the previous scene twice in this new scene, each with their names prefixed with eithersub1.
orsub2.
Under
entities
, we can override the entities in the sub-scenes to edit components or add new ones. For example, by referencingsub1.root
we are making local changes to theroot
entity of that instance of the subscene. The result of the changes we make to bothsub1.root
andsub2.root
is that the parent of these entities will be set to be themain
entity.Now that we have our scene file, let's get our application to load it. The first thing we're going to need is a reference to the scene asset. For the purposes of this sample we can simply use an hardcoded reference to the asset.
static const Asset<Scene> SceneAsset = AnyAsset("f0d86ba8-5f34-440f-a180-d9d12c8e8b91");Then we'll need a system that spawns that scene. To do this we simply get the Scene object from the asset, and then spawn its entities. Commands::
spawn will create in the world a copy of every entity defined in the scene's blueprint. It won't remove the entities already there, so if you want to close a scene, you'll have to do it yourself. static void spawnScene(Commands commands, Read<Assets> assets) { auto sceneRead = assets->read(SceneAsset); commands.spawn(sceneRead->blueprint); -}And now we'll have this system run at startup. It is not required, you can spawn scenes at any point in the execution of the program, but for the purpose of demonstrating the functionality, spawning once at startup is enough.
cubos.startupSystem(spawnScene).tagged("spawn").tagged("cubos.assets");Finally, let's print the loaded scene, to check that everything is working correctly.
static void printStuff(Read<World> world) -{ - using cubos::core::data::Context; - using cubos::core::data::DebugSerializer; - using cubos::core::data::SerializationMap; - using cubos::core::memory::Stream; - - for (auto entity : *world) - { - auto name = std::to_string(entity.index); - auto ser = DebugSerializer(Stream::stdOut); - auto pkg = world->pack(entity); - ser.write(pkg, name.c_str()); - Stream::stdOut.put('\n'); - } -}If you run the sample, it should give you a list that has:
num
set to 0, with no parent. This is the main
entity.num
set to 1, with same parent, who has num
set to 0. These are the root
entities of each instance of the subscene.num
set to 2, with different parents, but both of them having num
set to 1. These are the child
entities of each instance of the subscene.In this case, we'll run this system at startup, since we want to spawn it a single time. Since it's a startup system, we'll have to tag it with cubos.assets
to make sure it runs only after the scene bridge has been registered. On a real game, you could have, for example, a scene for an enemy which you spawn multiple times, instead of just once at startup.
cubos.startupSystem(spawnScene).tagged("spawn").tagged("cubos.assets");
This sample will output the list of every entity in the scene, so you can check that everything is working as expected. If you run it, it should give you a list that has:
num
set to 0, with no parent. This is the main
entity.num
set to 1, with same parent, who has num
set to 0. These are the root
entities of each instance of the subscene.num
set to 2, with different parents, but both of them having num
set to 1. These are the child
entities of each instance of the subscene..cubos
extension, loads Scene assets..cubos
extension, loads Scene assets.