Skip to content

Commit

Permalink
Deploy preview for PR 915 🛫
Browse files Browse the repository at this point in the history
  • Loading branch information
RiscadoA committed Jan 30, 2024
1 parent 6abde62 commit c7fffb2
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions docs-preview/pr-915/examples-engine-scene.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,41 @@ <h1>
</h1>
<p>Using the <a href="group__scene-plugin.html" class="m-doc">Scene</a> plugin.</p>
<p><a name="md_scene_page"></a></p><aside class="m-note m-default"><h4>See also</h4><p>Full source code <a href="https://github.com/GameDevTecnico/cubos/tree/main/engine/samples/scene">here</a>.</p></aside><p>This example shows how the <a href="group__scene-plugin.html" class="m-doc">Scene</a> plugin can be used to create scene assets and spawn them on the world.</p><p>The plugin function is included from the <a href="engine_2include_2cubos_2engine_2scene_2plugin_8hpp.html" class="m-doc">engine/<wbr />scene/<wbr />plugin.hpp</a> header.</p><pre class="m-code"><span class="w"> </span><span class="n">cubos</span><span class="p">.</span><span class="n">addPlugin</span><span class="p">(</span><span class="n">scenePlugin</span><span class="p">);</span></pre><p>Let&#x27;s start by taking a look at a scene file.</p><pre class="m-code">{
&quot;imports&quot;: {},
&quot;entities&quot;: {
&quot;main&quot;: {
&quot;cubos::engine::Position&quot;: {
&quot;x&quot;: 2,
&quot;y&quot;: 2,
&quot;z&quot;: 2
}
}
&quot;imports&quot;: {},
&quot;entities&quot;: {
&quot;root&quot;: {
&quot;Num&quot;: 1
},
&quot;child&quot;: {
&quot;Num&quot;: 2,
&quot;OwnedBy&quot;: &quot;root&quot;
}
}</pre><p>Scene files are JSON files with the extension <code>.cubos</code>. They must have two fields: <code>imports</code> and <code>entities</code>. The <code>entities</code> field is an object where each field identifies and describes the components of an entity. In this scene we have two entities, <code>root</code> and <code>child</code>. <code>root</code> has a single component, <code>num</code>, with a value of 1. <code>child</code> has two components, a <code>parent</code> and a <code>num</code>. In this sample, <code>num</code> is used so we can later identify the entities.</p><aside class="m-note m-info"><h4>Note</h4><p>Make sure these component names match the ones in your application and that they have been registered with <a href="namespacecubos_1_1engine.html#afa0b202a1b9f7ddf7c42db16c8dbb7ba" class="m-doc">Cubos</a>.</p></aside><p>Let&#x27;s look at a different scene file now, this time with <code>imports</code>. Imports allows us to instantiate scenes within other scenes.</p><pre class="m-code">{
}
}</pre><p>Scene files are JSON files with the extension <code>.cubos</code>. They must have two fields: <code>imports</code> and <code>entities</code>. The <code>entities</code> field is an object where each field identifies and describes the components and relations of an entity. In this scene we have two entities, <code>root</code> and <code>child</code>. <code>root</code> has a single component, <code>Num</code>, with a value of 1. <code>child</code> too has a component <code>Num</code>, but also has a relation <code>OwnedBy</code> with <code>root</code> as target. In this sample, <code>Num</code> is used so we can later identify the entities.</p><aside class="m-note m-info"><h4>Note</h4><p>Make sure these component names match the ones in your application and that they have been registered with <a href="namespacecubos_1_1engine.html#afa0b202a1b9f7ddf7c42db16c8dbb7ba" class="m-doc">Cubos</a>.</p></aside><p>Let&#x27;s look at a different scene file now, this time with <code>imports</code>. Imports allows us to instantiate scenes within other scenes.</p><pre class="m-code">{
&quot;imports&quot;: {
&quot;sub1&quot;: &quot;00d86ba8-5f34-440f-a180-d9d12c8e8b91&quot;
&quot;sub1&quot;: &quot;cd007ba2-ee0d-44fd-bf36-85c829dbe66f&quot;,
&quot;sub2&quot;: &quot;cd007ba2-ee0d-44fd-bf36-85c829dbe66f&quot;
},
&quot;entities&quot;: {
&quot;main&quot;: {
&quot;cubos::engine::Position&quot;: {
&quot;x&quot;: 1,
&quot;y&quot;: 1,
&quot;z&quot;: 1
&quot;Num&quot;: 0
},
&quot;sub1.root&quot;: {
&quot;OwnedBy&quot;: &quot;main&quot;,
&quot;DistanceTo&quot;: {
&quot;entity&quot;: &quot;sub2.root&quot;,
&quot;value&quot;: 5
}
},
&quot;sub2.root&quot;: {
&quot;OwnedBy&quot;: &quot;main&quot;
}
}
}</pre><p>This file imports the asset with id <code>cd007ba2-ee0d-44fd-bf36-85c829dbe66f</code>, which is the scene we looked at in the previous file, under the name <code>sub1</code>. It then imports the very same scene again, but this time with the name <code>sub2</code> instead. This effectively instantiates the entities of the previous scene twice in this new scene, each with their names prefixed with either <code>sub1.</code> or <code>sub2.</code></p><p>Under <code>entities</code>, we can override the entities in the sub-scenes to edit components or add new ones. For example, by referencing <code>sub1.root</code> we are making local changes to the <code>root</code> entity of that instance of the subscene. The result of the changes we make to both <code>sub1.root</code> and <code>sub2.root</code> is that the parent of these entities will be set to be the <code>main</code> entity.</p><p>Now that we have our scene file, let&#x27;s get our application to load it. The first thing we&#x27;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.</p><pre class="m-code"><span class="k">static</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">Asset</span><span class="o">&lt;</span><span class="n">Scene</span><span class="o">&gt;</span><span class="w"> </span><span class="n">SceneAsset</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AnyAsset</span><span class="p">(</span><span class="s">&quot;f0d86ba8-5f34-440f-a180-d9d12c8e8b91&quot;</span><span class="p">);</span></pre><p>Then we&#x27;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. <a href="classcubos_1_1core_1_1ecs_1_1Commands.html#a0c75cfde6373904798ba117b9627cd5f" class="m-doc">Commands::<wbr />spawn</a> will create in the world a copy of every entity defined in the scene&#x27;s blueprint. It won&#x27;t remove the entities already there, so if you want to close a scene, you&#x27;ll have to do it yourself.</p><pre class="m-code"><span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">spawnScene</span><span class="p">(</span><span class="n">Commands</span><span class="w"> </span><span class="n">commands</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">Assets</span><span class="o">&amp;</span><span class="w"> </span><span class="n">assets</span><span class="p">)</span>
}</pre><p>This file imports the asset with id <code>cd007ba2-ee0d-44fd-bf36-85c829dbe66f</code>, which is the scene we looked at in the previous file, under the name <code>sub1</code>. It then imports the very same scene again, but this time with the name <code>sub2</code> instead. This effectively instantiates the entities of the previous scene twice in this new scene, each with their names prefixed with either <code>sub1.</code> or <code>sub2.</code></p><p>Also take a look at the <code>DistanceTo</code> relation: it is a symmetric relation, so it doesn&#x27;t make a different whether wwe put it in <code>sub.root</code> or <code>sub2.root</code>. Since <code>DistanceTo</code> is a relation which holds data, instead of only specifying the target, as we do with <code>OwnedBy</code>, we write a JSON object with two keys, <code>&quot;entity&quot;</code> and <code>&quot;value&quot;</code>.</p><p>Under <code>entities</code>, we can override the entities in the sub-scenes to edit components or add new ones. For example, by referencing <code>sub1.root</code> we are making local changes to the <code>root</code> entity of that instance of the subscene. The result of the changes we make to both <code>sub1.root</code> and <code>sub2.root</code> is that the owner of these entities will be set to be the <code>main</code> entity.</p><p>Now that we have our scene file, let&#x27;s get our application to load it. The first thing we&#x27;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.</p><pre class="m-code"><span class="k">static</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">Asset</span><span class="o">&lt;</span><span class="n">Scene</span><span class="o">&gt;</span><span class="w"> </span><span class="n">SceneAsset</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AnyAsset</span><span class="p">(</span><span class="s">&quot;f0d86ba8-5f34-440f-a180-d9d12c8e8b91&quot;</span><span class="p">);</span></pre><p>Then we&#x27;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. <a href="classcubos_1_1core_1_1ecs_1_1Commands.html#a0c75cfde6373904798ba117b9627cd5f" class="m-doc">Commands::<wbr />spawn</a> will create in the world a copy of every entity defined in the scene&#x27;s blueprint. It won&#x27;t remove the entities already there, so if you want to close a scene, you&#x27;ll have to do it yourself.</p><pre class="m-code"><span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">spawnScene</span><span class="p">(</span><span class="n">Commands</span><span class="w"> </span><span class="n">commands</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">Assets</span><span class="o">&amp;</span><span class="w"> </span><span class="n">assets</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">auto</span><span class="w"> </span><span class="n">sceneRead</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">assets</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">SceneAsset</span><span class="p">);</span>
<span class="w"> </span><span class="n">commands</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="n">sceneRead</span><span class="o">-&gt;</span><span class="n">blueprint</span><span class="p">);</span>
<span class="p">}</span></pre><p>In this case, we&#x27;ll run this system at startup, since we want to spawn it a single time. Since it&#x27;s a startup system, we&#x27;ll have to tag it with <code>cubos.assets</code> 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.</p><pre class="m-code"><span class="w"> </span><span class="n">cubos</span><span class="p">.</span><span class="n">startupSystem</span><span class="p">(</span><span class="n">spawnScene</span><span class="p">).</span><span class="n">tagged</span><span class="p">(</span><span class="s">&quot;spawn&quot;</span><span class="p">).</span><span class="n">tagged</span><span class="p">(</span><span class="s">&quot;cubos.assets&quot;</span><span class="p">);</span></pre><p>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:</p><ul><li>an entity with <code>num</code> set to 0, with no parent. This is the <code>main</code> entity.</li><li>two entities with <code>num</code> set to 1, with same parent, who has <code>num</code> set to 0. These are the <code>root</code> entities of each instance of the subscene.</li><li>two entities with <code>num</code> set to 2, with different parents, but both of them having <code>num</code> set to 1. These are the <code>child</code> entities of each instance of the subscene.</li></ul>
<span class="p">}</span></pre><p>In this case, we&#x27;ll run this system at startup, since we want to spawn it a single time. Since it&#x27;s a startup system, we&#x27;ll have to tag it with <code>cubos.assets</code> 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.</p><pre class="m-code"><span class="w"> </span><span class="n">cubos</span><span class="p">.</span><span class="n">startupSystem</span><span class="p">(</span><span class="n">spawnScene</span><span class="p">).</span><span class="n">tagged</span><span class="p">(</span><span class="s">&quot;spawn&quot;</span><span class="p">).</span><span class="n">tagged</span><span class="p">(</span><span class="s">&quot;cubos.assets&quot;</span><span class="p">);</span></pre><p>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:</p><ul><li>an entity with <code>Num</code> set to 0, with no owner. This is the <code>main</code> entity.</li><li>two entities with <code>Num</code> set to 1, both owned by <code>main</code>. These are the <code>root</code> entities of each instance of the subscene.</li><li>two entities with <code>Num</code> set to 2, one owned by one of the <code>root</code> entities, another owned by the other <code>root</code> entity. These are the <code>child</code> entities of each instance of the subscene. Notice that both are related with a <code>DistanceTo</code> relation set to <code>5</code>.</li></ul>
</div>
</div>
</div>
Expand Down

0 comments on commit c7fffb2

Please sign in to comment.