diff --git a/docs-preview/pr-915/examples-engine-scene.html b/docs-preview/pr-915/examples-engine-scene.html index 3fe8783fb..d4849c811 100644 --- a/docs-preview/pr-915/examples-engine-scene.html +++ b/docs-preview/pr-915/examples-engine-scene.html @@ -52,34 +52,41 @@

Using the Scene plugin.

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": {
-        "main": {
-            "cubos::engine::Position": {
-                "x": 2,
-                "y": 2,
-                "z": 2
-            }
-        }
+  "imports": {},
+  "entities": {
+    "root": {
+      "Num": 1
+    },
+    "child": {
+      "Num": 2,
+      "OwnedBy": "root"
     }
-}

Scene files are JSON files with the extension .cubos. They must have two fields: imports and entities. The entities field is an object where each field identifies and describes the components of an entity. In this scene we have two entities, root and child. root has a single component, num, with a value of 1. child has two components, a parent and a num. 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.

{
+  }
+}

Scene files are JSON files with the extension .cubos. They must have two fields: imports and entities. The entities field is an object where each field identifies and describes the components and relations of an entity. In this scene we have two entities, root and child. root has a single component, Num, with a value of 1. child too has a component Num, but also has a relation OwnedBy with root as target. 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": "00d86ba8-5f34-440f-a180-d9d12c8e8b91"
+    "sub1": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f",
+    "sub2": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f"
   },
   "entities": {
     "main": {
-      "cubos::engine::Position": {
-        "x": 1,
-        "y": 1,
-        "z": 1
+      "Num": 0
+    },
+    "sub1.root": {
+      "OwnedBy": "main",
+      "DistanceTo": {
+        "entity": "sub2.root",
+        "value": 5
       }
+    },
+    "sub2.root": {
+      "OwnedBy": "main"
     }
   }
-}

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 name sub1. It then imports the very same scene again, but this time with the name sub2 instead. This effectively instantiates the entities of the previous scene twice in this new scene, each with their names prefixed with either sub1. or sub2.

Under entities, we can override the entities in the sub-scenes to edit components or add new ones. For example, by referencing sub1.root we are making local changes to the root entity of that instance of the subscene. The result of the changes we make to both sub1.root and sub2.root is that the parent of these entities will be set to be the main 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, const 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 name sub1. It then imports the very same scene again, but this time with the name sub2 instead. This effectively instantiates the entities of the previous scene twice in this new scene, each with their names prefixed with either sub1. or sub2.

Also take a look at the DistanceTo relation: it is a symmetric relation, so it doesn't make a different whether wwe put it in sub.root or sub2.root. Since DistanceTo is a relation which holds data, instead of only specifying the target, as we do with OwnedBy, we write a JSON object with two keys, "entity" and "value".

Under entities, we can override the entities in the sub-scenes to edit components or add new ones. For example, by referencing sub1.root we are making local changes to the root entity of that instance of the subscene. The result of the changes we make to both sub1.root and sub2.root is that the owner of these entities will be set to be the main 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, const Assets& assets)
 {
     auto sceneRead = assets.read(SceneAsset);
     commands.spawn(sceneRead->blueprint);
-}

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:

+}

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 also contains a system which prints the components and relations of the spawned entities. If you run it, it should give you a list that has: