Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Змінюйте сцени вручну
Іноді допомагає краще контролювати, як ви змінюєте сцени. Дочірні вузли Viewport будуть відтворювати зображення, яке воно генерує. Це справедливо навіть для вузлів за межами «поточної» сцени. До цієї категорії належать автозавантаження, а також сцени, які ви створюєте та додаєте до дерева під час виконання:
var simultaneous_scene = preload("res://levels/level2.tscn").instantiate()
func _add_a_scene_manually():
# This is like autoloading the scene, only
# it happens after already loading the main scene.
get_tree().root.add_child(simultaneous_scene)
public Node simultaneousScene;
public MyClass()
{
simultaneousScene = ResourceLoader.Load<PackedScene>("res://levels/level2.tscn").Instantiate();
}
public void _AddASceneManually()
{
// This is like autoloading the scene, only
// it happens after already loading the main scene.
GetTree().Root.AddChild(simultaneousScene);
}
Щоб завершити цикл і замінити нову сцену на стару, вам потрібно зробити вибір. Існує багато стратегій для видалення сцени з поля зору Viewport. Компроміси передбачають збалансування швидкості роботи та споживання пам’яті, а також збалансування доступу та цілісності даних.
Видалити наявну сцену. SceneTree.change_scene_to_file() і SceneTree.change_scene_to_packed() негайно видалять поточну сцену. Ви також можете видалити головну сцену. Якщо припустити, що кореневий вузол має назву «Main», ви можете виконати
get_node("/root/Main").free(), щоб видалити всю сцену.Розвантажує пам'ять.
Плюси: оперативна пам’ять більше не тягне мертвим вантажем.
Мінус: повернення до цієї сцени тепер дорожче, оскільки її потрібно знову завантажити в пам’ять (потрібен час І пам’ять). Не проблема, якщо незабаром повертатися не потрібно.
Мінус: більше немає доступу до даних цієї сцени. Не проблема, якщо використання цих даних незабаром стане непотрібним.
Примітка. Може бути корисно зберегти дані в сцені, яку незабаром буде видалено, повторно приєднавши один або більше її вузлів до іншої сцени або навіть безпосередньо до SceneTree.
Обробка зупинок.
За: відсутність вузлів означає відсутність обробки, фізичної обробки чи обробки вхідних даних. ЦП доступний для роботи з вмістом нової сцени.
Мінус: обробка та обробка вхідних даних цих вузлів більше не працюють. Не проблема, якщо використання оновлених даних не потрібне.
Приховати існуючу сцену. Змінюючи видимість або виявлення зіткнень вузлів, ви можете приховати все піддерево вузлів з точки зору гравця. Використовуйте CanvasItem.hide(), щоб приховати сцену, та CanvasItem.show(), щоб показати її знову.
Пам'ять все ще існує.
Pro: Ви все ще можете отримати доступ до даних, якщо це необхідно.
Профі: немає необхідності переміщувати вузли, щоб зберегти дані.
Мінус: у пам’яті зберігається більше даних, що стане проблемою для чутливих до пам’яті платформ, таких як Інтернет або мобільні пристрої.
Обробка продовжень.
Pro: Дані продовжують отримувати оновлення обробки, тому сцена зберігатиме будь-які дані в ній, які залежать від дельта-часу або даних кадру, оновленими.
За: вузли все ще є членами груп (оскільки групи належать до SceneTree).
Мінус: увага центрального процесора тепер розподілена між обома сценами. Занадто велике навантаження може призвести до низької частоти кадрів. Ви повинні обов’язково перевіряти продуктивність під час роботи, щоб переконатися, що цільова платформа може витримати навантаження від цього підходу.
Видалити існуючу сцену з дерева. Призначити змінну кореневому вузлу існуючої сцени. Потім використати Node.remove_child(Node), щоб від’єднати всю сцену від дерева. Щоб приєднати її пізніше, використати Node.add_child(Node).
Пам’ять все ще існує (плюси/мінуси схожі на приховування її від очей).
Обробка припиняється (плюси/мінуси аналогічні повному видаленню).
За: цей варіант «приховування» набагато легше показати/приховати. Замість того, щоб потенційно відстежувати численні зміни сцени, вам потрібно лише викликати методи add/remove_child. Це схоже на відключення ігрових об’єктів в інших двигунах.
Мінус: на відміну від приховування лише для перегляду, дані, що містяться в сцені, стануть застарілими, якщо вони покладаються на дельта-час, вхідні дані, групи чи інші дані, отримані від доступу SceneTree.
Існують також випадки, коли вам може знадобитися мати багато сцен одночасно, наприклад, додати свій власний синглтон під час виконання або зберегти дані сцени між змінами сцени (додавання сцени до кореневого вузла).
get_tree().root.add_child(scene)
GetTree().Root.AddChild(scene);
Іншим випадком може бути відображення кількох сцен одночасно за допомогою SubViewportContainers. Це оптимально для рендерингу різного вмісту в різних частинах екрана (наприклад, міні-карти, багатокористувацька гра з розділеним екраном).
Кожен варіант матиме випадки, коли він найкраще підходить, тому ви повинні перевірити наслідки кожного підходу та визначити, який шлях найкраще підходить для вашої унікальної ситуації.