virtualx-engine-docs/_sources/getting_started/step_by_step/instancing.rst.txt
2024-10-23 09:41:33 -07:00

219 lines
8.7 KiB
ReStructuredText

.. _doc_instancing:
Creating instances
==================
In the previous part, we saw that a scene is a collection of nodes organized in
a tree structure, with a single node as its root. You can split your project
into any number of scenes. This feature helps you break down and organize your
game's different components.
You can create as many scenes as you'd like and save them as files with the
``.tscn`` extension, which stands for "text scene". The ``Label.tscn`` file from
the previous lesson was an example. We call those files "Packed Scenes" as they
pack information about your scene's content.
Here's an example of a ball. It's composed of a :ref:`RigidBody2D
<class_RigidBody2D>` node as its root named Ball, which allows the ball to fall
and bounce on walls, a :ref:`Sprite <class_Sprite>` node, and a
:ref:`CollisionShape2D <class_CollisionShape2D>`.
.. image:: img/instancing_ball_scene.png
Once you saved a scene, it works as a blueprint: you can reproduce it in other
scenes as many times as you'd like. Replicating an object from a template like
this is called **instancing**.
.. image:: img/instancing_ball_instances_example.png
As we mentioned in the previous part, instanced scenes behave like a node: the
editor hides their content by default. When you instance the Ball, you only see
the Ball node. Notice also how each duplicate has a unique name.
Every instance of the Ball scene starts with the same structure and properties
as ``Ball.tscn``. However, you can modify each independently, such as changing
how they bounce, how heavy they are, or any property exposed by the source
scene.
In practice
-----------
Let's use instancing in practice to see how it works in Godot. We invite
you to download the ball's sample project we prepared for you:
:download:`instancing.zip <files/instancing.zip>`.
Extract the archive on your computer. Then, open Godot, and in the project
manager, click the Import button to import the project.
.. image:: img/instancing_import_button.png
In the pop-up that appears, click the browse button and navigate to the folder
you extracted.
.. image:: img/instancing_import_browse.png
Double-click the ``project.godot`` file to open it.
.. image:: img/instancing_import_project_file.png
Finally, click the Import & Edit button.
.. image:: img/instancing_import_and_edit_button.png
The project contains two packed scenes: ``Main.tscn``, containing walls against
which the ball collides, and ``Ball.tscn``. The Main scene should open
automatically.
.. image:: img/instancing_main_scene.png
Let's add a ball as a child of the Main node. In the Scene dock, select the Main
node. Then, click the link icon at the top of the scene dock. This button allows
you to add an instance of a scene as a child of the currently selected node.
.. image:: img/instancing_scene_link_button.png
Double-click the ball scene to instance it.
.. image:: img/instancing_instance_child_window.png
The ball appears in the top-left corner of the viewport.
.. image:: img/instancing_ball_instanced.png
Click on it and drag it towards the center of the view.
.. image:: img/instancing_ball_moved.png
Play the game by pressing F5. You should see it fall.
Now, we want to create more instances of the Ball node. With the ball still
selected, press :kbd:`Ctrl-D` (:kbd:`Cmd-D` on macOS) to call the duplicate
command. Click and drag to move the new ball to a different location.
.. image:: img/instancing_ball_duplicated.png
You can repeat this process until you have several in the scene.
.. image:: img/instancing_main_scene_with_balls.png
Play the game again. You should now see every ball fall independently from one
another. This is what instances do. Each is an independent reproduction of a
template scene.
Editing scenes and instances
----------------------------
There is more to instances. With this feature, you can:
1. Change the properties of one ball without affecting the others using the
Inspector.
2. Change the default properties of every Ball by opening the ``Ball.tscn`` scene
and making a change to the Ball node there. Upon saving, all instances of the
Ball in the project will see their values update.
.. note:: Changing a property on an instance always overrides values from the
corresponding packed scene.
Let's try this. Open ``Ball.tscn`` and select the Ball node. In the Inspector on
the right, click on the PhysicsMaterial property to expand it.
.. image:: img/instancing_physics_material_expand.webp
Set its Bounce property to ``0.5`` by clicking on the number field, typing ``0.5``,
and pressing :kbd:`Enter`.
.. image:: img/instancing_property_bounce_updated.webp
Play the game by pressing :kbd:`F5` and notice how all balls now bounce a lot
more. As the Ball scene is a template for all instances, modifying it and saving
causes all instances to update accordingly.
Let's now adjust an individual instance. Head back to the Main scene by clicking
on the corresponding tab above the viewport.
.. image:: img/instancing_scene_tabs.png
Select one of the instanced Ball nodes and, in the Inspector, set its Gravity
Scale value to ``10``.
.. image:: img/instancing_property_gravity_scale.png
A grey "revert" button appears next to the adjusted property.
.. image:: img/instancing_property_revert_icon.png
This icon indicates you are overriding a value from the source packed scene.
Even if you modify the property in the original scene, the value override will
be preserved in the instance. Clicking the revert icon will restore the
property to the value in the saved scene.
Rerun the game and notice how this ball now falls much faster than the others.
.. note:: If you change a value on the ``PhysicsMaterial`` of one instance, it
will affect all the others. This is because ``PhysicsMaterial`` is a
resource, and resources are shared between instances. To make a
resource unique for one instance, right-click on it in the Inspector
and click Make Unique in the contextual menu.
Resources are another essential building block of Godot games we will
cover in a later lesson.
Scene instances as a design language
------------------------------------
Instances and scenes in Godot offer an excellent design language, setting the
engine apart from others out there. We designed Godot around this concept from
the ground up.
We recommend dismissing architectural code patterns when making games with
Godot, such as Model-View-Controller (MVC) or Entity-Relationship diagrams.
Instead, you can start by imagining the elements players will see in your game
and structure your code around them.
For example, you could break down a shooter game like so:
.. image:: img/instancing_diagram_shooter.png
You can come up with a diagram like this for almost any type of game. Each
rectangle represents an entity that's visible in the game from the player's
perspective. The arrows tell you which scene owns which.
Once you have a diagram, we recommend creating a scene for each element listed
in it to develop your game. You'll use instancing, either by code or directly in
the editor, to build your tree of scenes.
Programmers tend to spend a lot of time designing abstract architectures and
trying to fit components into it. Designing based on scenes makes development
faster and more straightforward, allowing you to focus on the game logic itself.
Because most game components map directly to a scene, using a design based on
scene instantiation means you need little other architectural code.
Here's the example of a scene diagram for an open-world game with tons of assets
and nested elements:
.. image:: img/instancing_diagram_open_world.png
Imagine we started by creating the room. We could make a couple of different
room scenes, with unique arrangements of furniture in them. Later, we could make
a house scene that uses multiple room instances for the interior. We would
create a citadel out of many instanced houses and a large terrain on which we
would place the citadel. Each of these would be a scene instancing one or more sub-scenes.
Later, we could create scenes representing guards and add them to the citadel.
They would be indirectly added to the overall game world.
With Godot, it's easy to iterate on your game like this, as all you need to do
is create and instantiate more scenes. We designed the editor to be accessible
to programmers, designers, and artists alike. A typical team development process
can involve 2D or 3D artists, level designers, game designers, and animators,
all working with the Godot editor.
Summary
-------
Instancing, the process of producing an object from a blueprint has many handy
uses. With scenes, it gives you:
- The ability to divide your game into reusable components.
- A tool to structure and encapsulate complex systems.
- A language to think about your game project's structure in a natural way.