From 5ad2139c6cb825b9c3fb18cabfecee0052a10764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diogo=20Mendon=C3=A7a?= Date: Thu, 21 Sep 2023 10:09:55 +0100 Subject: [PATCH] docs(engine): document Scene sample --- docs/pages/3_examples/2_engine/main.md | 1 + engine/include/cubos/engine/scene/plugin.hpp | 2 + engine/samples/scene/main.cpp | 12 ++++ engine/samples/scene/page.md | 59 ++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 engine/samples/scene/page.md diff --git a/docs/pages/3_examples/2_engine/main.md b/docs/pages/3_examples/2_engine/main.md index 4b1b98031..f395d8e40 100644 --- a/docs/pages/3_examples/2_engine/main.md +++ b/docs/pages/3_examples/2_engine/main.md @@ -7,3 +7,4 @@ multiple plugins of the engine: - @subpage examples-engine-settings - @copybrief examples-engine-settings - @subpage examples-engine-renderer - @copybrief examples-engine-renderer +- @subpage examples-engine-scene - @copybrief examples-engine-scene \ No newline at end of file diff --git a/engine/include/cubos/engine/scene/plugin.hpp b/engine/include/cubos/engine/scene/plugin.hpp index a2dc8c34a..aa12c15e2 100644 --- a/engine/include/cubos/engine/scene/plugin.hpp +++ b/engine/include/cubos/engine/scene/plugin.hpp @@ -15,6 +15,8 @@ namespace cubos::engine /// @defgroup scene-plugin Scene /// @ingroup engine /// @brief Adds scenes to @b CUBOS. + /// @see Take a look at the @ref examples-engine-scene example for a demonstration of this + /// plugin. /// /// ## Bridges /// - @ref SceneBridge - registered with the `.cubos` extension, loads @ref Scene assets. diff --git a/engine/samples/scene/main.cpp b/engine/samples/scene/main.cpp index 2fa1de305..47daf0b11 100644 --- a/engine/samples/scene/main.cpp +++ b/engine/samples/scene/main.cpp @@ -15,19 +15,24 @@ using cubos::core::ecs::Write; using namespace cubos::engine; +/// [Setting the asset] static const Asset SceneAsset = AnyAsset("f0d86ba8-5f34-440f-a180-d9d12c8e8b91"); +/// [Setting the asset] static void settings(Write settings) { settings->setString("assets.io.path", SAMPLE_ASSETS_FOLDER); } +/// [Spawning the scene] static void spawnScene(Commands commands, Read assets) { auto sceneRead = assets->read(SceneAsset); commands.spawn(sceneRead->blueprint); } +/// [Spawning the scene] +/// [Displaying the scene] static void printStuff(Read world) { using cubos::core::data::Context; @@ -44,18 +49,25 @@ static void printStuff(Read world) Stream::stdOut.put('\n'); } } +/// [Displaying the scene] int main(int argc, char** argv) { Cubos cubos(argc, argv); + /// [Adding the plugin] cubos.addPlugin(scenePlugin); + /// [Adding the plugin] cubos.addComponent(); cubos.addComponent(); cubos.startupSystem(settings).tagged("cubos.settings"); + + /// [Adding the system] cubos.startupSystem(spawnScene).tagged("spawn").tagged("cubos.assets"); + /// [Adding the system] + cubos.startupSystem(printStuff).after("spawn"); cubos.run(); } diff --git a/engine/samples/scene/page.md b/engine/samples/scene/page.md new file mode 100644 index 000000000..285c4c0de --- /dev/null +++ b/engine/samples/scene/page.md @@ -0,0 +1,59 @@ +# Scene {#examples-engine-scene} + +@brief Using the @ref scene-plugin plugin. + +This example shows how the @ref scene-plugin plugin can be used to create +scene assets and spawn them on the world. + +The plugin function is included from the @ref engine/scene/plugin.hpp header. + +@snippet scene/main.cpp Adding the plugin + +Let's start by taking a look at a scene file. +@include assets/sub.cubos + +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. + +@note Make sure these component names match the ones in your application and that they have been registered with @ref cubos::engine::Cubos "Cubos". + +Let's look at a different scene file now, this time with `imports`. Imports allows us to instantiate scenes within other scenes. + +@include assets/main.cubos + +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. + +@snippet scene/main.cpp Setting the asset + +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. +@ref cubos::core::ecs::Commands::spawn "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. + +@snippet scene/main.cpp Spawning the scene + +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. + +@snippet scene/main.cpp Adding the system + +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: +- an entity with `num` set to 0, with no parent. This is the `main` entity. +- two entities with `num` set to 1, with same parent, who has `num` set to 0. These are the `root` entities of each instance of the subscene. +- two entities with `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.