|
@@ -1,127 +1,59 @@
|
|
|
.. _doc_what_are_godot_classes:
|
|
|
|
|
|
-Godot scenes and scripts are classes
|
|
|
-====================================
|
|
|
-
|
|
|
-In Godot, scripts and scenes can both be the equivalent of classes in an
|
|
|
-Object-Oriented programming language. The main difference is that scenes are
|
|
|
-`declarative code <https://en.wikipedia.org/wiki/Declarative_programming>`_,
|
|
|
-while scripts can contain `imperative code
|
|
|
-<https://en.wikipedia.org/wiki/Imperative_programming>`_.
|
|
|
-
|
|
|
-As a result, many best practices in Godot boil down to applying Object-Oriented
|
|
|
-design principles to the scenes, nodes, or scripts that make up your game.
|
|
|
-
|
|
|
-This guide explains how scripts and scenes work in the engine's core, to help
|
|
|
-you get a sense of how Godot works under the hood, and to help you better
|
|
|
-understand where some of this series' best practices come from.
|
|
|
-
|
|
|
-Making sense of classes in Godot
|
|
|
---------------------------------
|
|
|
-
|
|
|
-Godot Engine provides built-in classes like :ref:`Node <class_Node>`.
|
|
|
-User-created types are not technically classes. Instead, they are resources that
|
|
|
-tell the engine a sequence of initializations to perform on one of the engine's
|
|
|
-built-in classes.
|
|
|
-
|
|
|
-Godot's internal classes have methods that register a class's data with a
|
|
|
-:ref:`ClassDB <class_ClassDB>`. This database provides runtime access to class
|
|
|
-information. ``ClassDB`` contains information about classes like:
|
|
|
-
|
|
|
-- properties
|
|
|
-- methods
|
|
|
-- constants
|
|
|
-- signals
|
|
|
-
|
|
|
-This ``ClassDB`` is what Objects check against when performing an operation like
|
|
|
-accessing a property or calling a method. ``ClassDB`` checks the database's
|
|
|
-records and the records of the Object's base types to see if the Object supports
|
|
|
-the operation.
|
|
|
-
|
|
|
-On the engine's side, every class defines a static ``_bind_methods()`` function
|
|
|
-that describes what C++ content it registers to the database and how. When you
|
|
|
-use the engine, you can extend the methods, properties, and signals available from
|
|
|
-the ``ClassDB`` by attaching a :ref:`Script <class_Script>` to your node.
|
|
|
-
|
|
|
-Objects check their attached script before the database. This is why scripts can
|
|
|
-override built-in methods. If a script defines a ``_get_property_list()`` method,
|
|
|
-Godot appends that data to the list of properties the Object fetches from the
|
|
|
-ClassDB. The same is true for other declarative code.
|
|
|
-
|
|
|
-Even scripts that don't inherit from a built-in type, i.e. scripts that don't
|
|
|
-start with the ``extends`` keyword, implicitly inherit from the engine's base
|
|
|
-:ref:`Reference <class_Reference>` class. This allows the Object to defer
|
|
|
-to the script's content where the engine logic deems appropriate.
|
|
|
-
|
|
|
-.. note::
|
|
|
-
|
|
|
- As a result, you can instance scripts without the ``extends`` keyword
|
|
|
- from code, but you cannot attach them to a :ref:`Node <class_Node>`
|
|
|
+Applying object-oriented principles in Godot
|
|
|
+============================================
|
|
|
|
|
|
+The engine offers two main ways to create reusable objects: scripts and scenes. Neither of these
|
|
|
+technically define classes under the hood.
|
|
|
|
|
|
-Scripting performances and PackedScene
|
|
|
---------------------------------------
|
|
|
+Still, many best practices using Godot involve applying object-oriented programming principles to
|
|
|
+the scripts and scenes that compose your game. That is why it's useful to understand how we can
|
|
|
+think of them as classes.
|
|
|
|
|
|
-As the size of Objects increases, the scripts' necessary size to create them
|
|
|
-grows much, much larger. Creating node hierarchies demonstrates this. Each
|
|
|
-individual Node's logic could be several hundred lines of code in length.
|
|
|
+This guide briefly explains how scripts and scenes work in the engine's core to help you understand
|
|
|
+how they work under the hood.
|
|
|
|
|
|
-Let's see a simple example of creating a single ``Node`` as a child. The code
|
|
|
-below creates a new ``Node``, changes its name, assigns a script to it, sets its
|
|
|
-future parent as its owner so it gets saved to disk along with it, and finally
|
|
|
-adds it as a child of the ``Main`` node:
|
|
|
+How scripts work in the engine
|
|
|
+------------------------------
|
|
|
|
|
|
-.. tabs::
|
|
|
- .. code-tab:: gdscript GDScript
|
|
|
+The engine provides built-in classes like :ref:`Node <class_Node>`. You can extend those to create
|
|
|
+derived types using a script.
|
|
|
|
|
|
- # Main.gd
|
|
|
- extends Node
|
|
|
+These scripts are not technically classes. Instead, they are resources that tell the engine a
|
|
|
+sequence of initializations to perform on one of the engine's built-in classes.
|
|
|
|
|
|
- func _init():
|
|
|
- var child = Node.new()
|
|
|
- child.name = "Child"
|
|
|
- child.script = preload("Child.gd")
|
|
|
- child.owner = self
|
|
|
- add_child(child)
|
|
|
+Godot's internal classes have methods that register a class's data with a :ref:`ClassDB
|
|
|
+<class_ClassDB>`. This database provides runtime access to class information. ``ClassDB`` contains
|
|
|
+information about classes like:
|
|
|
|
|
|
- .. code-tab:: csharp
|
|
|
+- Properties.
|
|
|
+- Methods.
|
|
|
+- Constants.
|
|
|
+- Signals.
|
|
|
|
|
|
- using System;
|
|
|
- using Godot;
|
|
|
+This ``ClassDB`` is what objects check against when performing an operation like accessing a
|
|
|
+property or calling a method. It checks the database's records and the object's base types' records
|
|
|
+to see if the object supports the operation.
|
|
|
|
|
|
- namespace ExampleProject
|
|
|
- {
|
|
|
- public class Main : Resource
|
|
|
- {
|
|
|
- public Node Child { get; set; }
|
|
|
+Attaching a :ref:`Script <class_Script>` to your object extends the methods, properties, and signals
|
|
|
+available from the ``ClassDB``.
|
|
|
|
|
|
- public Main()
|
|
|
- {
|
|
|
- Child = new Node();
|
|
|
- Child.Name = "Child";
|
|
|
- Child.Script = (Script)ResourceLoader.Load("child.gd");
|
|
|
- Child.Owner = this;
|
|
|
- AddChild(Child);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+.. note::
|
|
|
|
|
|
-Script code like this is much slower than engine-side C++ code. Each change
|
|
|
-makes a separate call to the scripting API which leads to many "look-ups" on the
|
|
|
-back-end to find the logic to execute.
|
|
|
+ Even scripts that don't use the ``extends`` keyword implicitly inherit from the engine's base
|
|
|
+ :ref:`Reference <class_Reference>` class. As a result, you can instantiate scripts without the
|
|
|
+ ``extends`` keyword from code. Since they extend ``Reference`` though, you cannot attach them to
|
|
|
+ a :ref:`Node <class_Node>`.
|
|
|
|
|
|
-Scenes help to avoid this performance issue. :ref:`PackedScene
|
|
|
-<class_PackedScene>`, the base type that scenes inherit from, are resources that
|
|
|
-use serialized data to create objects. The engine can process scenes in batches
|
|
|
-on the back-end and provide much better performance than scripts.
|
|
|
+Scenes
|
|
|
+------
|
|
|
|
|
|
-Scenes and scripts are objects
|
|
|
-------------------------------
|
|
|
+The behavior of scenes has many similarities to classes, so it can make sense to think of a scene as
|
|
|
+a class. Scenes are reusable, instantiable, and inheritable groups of nodes. Creating a scene is
|
|
|
+similar to having a script that creates nodes and adds them as children using ``add_child()``.
|
|
|
|
|
|
-Why is any of this important to scene organization? Because scenes *are*
|
|
|
-objects. One often pairs a scene with a scripted root node that makes use of the
|
|
|
-sub-nodes. This means that the scene is often an extension of the script's
|
|
|
-declarative code.
|
|
|
+We often pair a scene with a scripted root node that makes use of the scene's nodes. As such, the
|
|
|
+scene is often an extension of the script's declarative code.
|
|
|
|
|
|
The content of a scene helps to define:
|
|
|
|
|
@@ -130,10 +62,11 @@ The content of a scene helps to define:
|
|
|
- How they are initialized
|
|
|
- What signal connections they have with each other
|
|
|
|
|
|
-Many Object-Oriented principles which apply to written code *also* apply to
|
|
|
-scenes.
|
|
|
+Why is any of this important to scene organization? Because instances of scenes *are* objects. As a
|
|
|
+result, many object-oriented principles that apply to written code also apply to scenes: single
|
|
|
+responsibility, encapsulation, and others.
|
|
|
|
|
|
-The scene is *always an extension of the script attached to its root node*. You
|
|
|
-can see all the nodes it contains as part of a single class.
|
|
|
+The scene is *always an extension of the script attached to its root node*, so you can interpret it
|
|
|
+as part of a class.
|
|
|
|
|
|
-Most of the tips and techniques explained in this series will build on this.
|
|
|
+Most of the techniques explained in this best practices series build on this point.
|