Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Використання Дерева сцени

Вступ

У попередніх уроках все оберталося навколо концепції вузлів. Сцени - це колекції вузлів. Вони стають активними, як тільки входять у дерево сцен.

MainLoop (Головний цикл)

Внутрішня робота Godot полягає в наступному. Існує клас OS, який є єдиним екземпляром, який запускається на початку. Після цього завантажуються всі драйвери, сервери, скриптові мови, система сцен тощо.

Коли ініціалізація завершена, OS потрібно для запуску MainLoop. До цього моменту все це внутрішня обробка (ви можете перевірити файл main/main.cpp у вихідному коді, якщо вам стане колись цікаво побачити, як це працює всередині).

Програма користувача, або гра, запускається в MainLoop. У цьому класі є кілька методів для ініціалізації, простою (зворотний синхронізований кадр), фіксації (фізичний синхронізований зворотний виклик) та введення. Однак це низький рівень, і при розробці ігор в Godot, рідко має сенс писати власний MainLoop.

Дерево Сцен

Суть роботи Godot полягає в тому, що це ігровий движок високого рівня заснований на програмному забезпеченні низького рівня.

Система сцен - це ігровий движок, тоді як OS і сервери - API низького рівня.

Система сцен забезпечує власний головний цикл для ОС, SceneTree. Він автоматично встановлюється і налаштовується під час запуску сцени, не потрібно робити зайвих робіт.

Важливо знати, про наявність цього класу, оскільки він має кілька важливих застосувань:

  • Він містить кореневий Viewport, до якого додається сцена в якості нащадка, при першому відкритті, щоб стати частиною Дерева сцен (докладніше про це далі).

  • Він містить інформацію про групи і має засоби для виклику всіх вузлів групи, або отримання їх списку.

  • Він містить деяку функціональність глобального стану, наприклад встановлення режиму паузи, або вихід.

Коли вузол є частиною дерева сцен, сиглтон (одиночний екземпляр) SceneTree можна отримати, викликавши Node.get_tree().

Кореневе вікно перегляду

Кореневе Viewport (Вікно перегляду) завжди знаходиться у верхній частині сцени. З вузла його можна отримати двома різними способами:

get_tree().root # Access via scene main loop.
get_node("/root") # Access via absolute path.

Цей вузол містить головне вікно перегляду. Всі нащадки Viewport, малюються всередині нього за замовчуванням, тому є сенс в тому, щоб коренем всіх вузлів завжди був вузол такого типу, інакше нічого не буде видно.

Хоча в сцені можуть створюватися інші вікна перегляду (для ефектів розділеного екрана і подібних речей), це єдине, яке ніколи не створюється користувачем. Воно створюється автоматично всередині SceneTree (дерева сцен).

Дерево сцени

Коли вузол підключений безпосередньо, або опосередковано, до кореневого вікна перегляду, він стає частиною дерева сцен.

This means that as explained in previous tutorials, it will get the _enter_tree() and _ready() callbacks (as well as _exit_tree()).

../../_images/activescene.webp

Коли вузли входять у дерево сцен, вони стають активними. Вони отримують доступ до всього необхідного для обробки, отримують введення, демонструють 2D та 3D-візуальні зображення, отримують та надсилають сповіщення, відтворюють звуки тощо. Коли їх видаляють із дерева сцен , вони втрачають ці здібності.

Послідовність в дереві

Most node operations in Godot, such as drawing 2D, processing, or getting notifications are done in tree order, or top to bottom as seen in the editor (also known as pre-order traversal):

../../_images/toptobottom.webp

For example, the top node in a scene has its _process() function called first, then the node below it has its _process() function called, then the node below that and so on.

An important exception is the _ready() function: each parent node has its _ready() function called only after all its child nodes have their _ready() functions called, so that the parent knows its children are completely ready to be accessed. This is also known as post-order traversal. In the above image, NameLabel would be notified first (but only after its children, if it had any!), followed by Name, etc., and Panel would be notified last.

The order of operations can also be overridden using the process_priority node property. Nodes with a lower number are called first. For example, nodes with the priorities "0, 1, 2, 3" would be called in that order from left to right.

"Становлення активним" при вході в дерево сцен

  1. Сцена завантажується з диска, або створюється скриптом.

  2. The root node of that scene (only one root, remember?) is added as either a child of the "root" Viewport (from SceneTree), or to any of its descendants.

  3. Every node of the newly added scene will receive the "enter_tree" notification ( _enter_tree() callback in GDScript) in top-to-bottom order (pre-order traversal).

  4. Every node will receive the "ready" notification ( _ready() callback in GDScript) for convenience, once all its children have received the "ready" notification (post-order traversal).

  5. Коли сцену (або її частину) видалено, вони отримують сповіщення про "вихід зі сцени" (зворотний виклик _exit_tree() у GDScript) у порядку знизу-вгору (зворотному порядку зверху-вниз).

Зміна поточної сцени

After a scene is loaded, you may want to change this scene for another one. One way to do this is to use the SceneTree.change_scene_to_file() function:

func _my_level_was_completed():
    get_tree().change_scene_to_file("res://levels/level2.tscn")

Rather than using file paths, one can also use ready-made PackedScene resources using the equivalent function SceneTree.change_scene_to_packed(PackedScene scene):

var next_scene = preload("res://levels/level2.tscn")

func _my_level_was_completed():
    get_tree().change_scene_to_packed(next_scene)

These are quick and useful ways to switch scenes but have the drawback that the game will stall until the new scene is loaded and running. At some point in the development of your game, it may be preferable to create proper loading screens with progress bar, animated indicators or threaded (background) loading. This must be done manually using Singletons (Autoload) and Тло завантаження.