Organisation des scènes dans Godot 4
Scène, script ou ressource
- Scène (
.tscn) : un arbre réutilisable de nœuds avec ses propres ressources : un joueur, un ennemi, un objet à ramasser, un panneau d'interface, un niveau. Tout ce que vous placez plus d'une fois ou voulez exécuter seul (F6) est une scène. - Script (
.gd) : comportement attaché à un seul nœud. Attachez-le à la racine de la scène qu'il contrôle, pas à un parent qui y accède de l'extérieur. - Script de ressource (
extends Resourceavecclass_name) : données sans nœud, comme les statistiques d'un objet, les définitions de vagues ou les données de sauvegarde, éditées dans l'Inspector et sauvegardées en.tres.
Une scène doit fonctionner lorsqu'elle est exécutée seule. Si elle a besoin de quelque chose de l'extérieur (une cible, un parent de spawn), exposez-le avec @export ou un signal plutôt qu'avec des chaînes de get_parent().
Instanciation de scènes
extends Node2D
@export var enemy_scene: PackedScene
@export var spawn_parent: Node2D
func spawn_enemy(at: Vector2) -> void:
var enemy := enemy_scene.instantiate() as Node2D
enemy.position = at
spawn_parent.add_child(enemy)
func load_level(path: String) -> void:
var packed := load(path) as PackedScene
if packed == null:
push_error("Niveau introuvable : " + path)
return
get_tree().change_scene_to_packed(packed)
@export var x: PackedScenese définit dans l'Inspector et survit aux déplacements de fichiers, car la scène stocke la référence.const BULLET := preload("res://bullet.tscn")se résout au moment de l'analyse syntaxique : un fichier manquant provoque une erreur d'analyse (Preload file "res://bullet.tscn" does not exist.). Idéal pour les ressources fixes.load()se résout à l'exécution et renvoienullavec une erreur si le chemin est incorrect. Utilisez-le pour les chemins construits à l'exécution.instantiate()(pasinstance()de Godot 3) renvoie unNode; castez-le vers le type souhaité. Libérez les instances avecqueue_free().
Recherche de nœuds
extends Control
@onready var title: Label = %Title
@onready var start_button: Button = %StartButton
@onready var music: AudioStreamPlayer = $Music
@onready var optional_hint: Label = get_node_or_null("Hint")
func _ready() -> void:
title.text = "Menu principal"
start_button.grab_focus()
if optional_hint:
optional_hint.visible = false
music.play()
$Pathest équivalent àget_node("Path"), relatif à ce nœud. Il génère une erreur si le nœud est manquant ; utilisezget_node_or_null()pour les nœuds optionnels.%Nameatteint un nœud marqué "Accès comme nom unique" (clic droit dans le dock Scène) n'importe où dans la même scène, ce qui survit au réparentage à l'intérieur de la scène. Il n'atteint pas les scènes enfants instanciées : utilisez$Child/%Name, ou%Child/%Namelorsque l'instance est elle-même unique.- Les variables
@onreadysont assignées juste avant_ready(). Elles sontnulldans_init()et_enter_tree(). _ready()s'exécute sur les enfants avant leur parent, donc le_ready()d'un parent peut utiliser ses enfants, mais le_ready()d'un enfant ne doit pas compter sur le fait que le parent soit prêt.- Typez les variables
@onready(: Label) pour que l'analyseur vérifie les noms des membres ;$Label.txtsur un chemin non typé n'est détecté qu'à l'exécution.
Groupes
Les groupes marquent des nœuds à travers les scènes. Ajoutez-les dans le dock Nœuds (onglet Groupes) ou en code, puis interrogez l'arbre :
extends Node
func _ready() -> void:
add_to_group("enemies")
func alert_all_enemies() -> void:
get_tree().call_group("enemies", "set_alerted", true)
for enemy in get_tree().get_nodes_in_group("enemies"):
print(enemy.name)
var player := get_tree().get_first_node_in_group("player") as Node2D
if player:
print("Joueur à ", player.global_position)
call_group() appelle immédiatement dans Godot 4. Utilisez get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED, ...) pour différer.
Autoloads
Un autoload est un nœud créé avant la scène principale et conservé lors des changements de scène. Utilisez-le pour l'état qui survit à une scène (paramètres, données de sauvegarde, changeur de scène) et pour un bus d'événements à base de signaux. Enregistrez-le dans Projet > Paramètres > Globals > Autoload ; project.godot contient alors :
[autoload]
Events="*res://autoload/events.gd"
Le * signifie que "Activer" est coché, donc les scripts peuvent utiliser le nom directement (Events.player_died.emit()). Ne free()z ou queue_free()z pas un autoload. Gardez les autoloads peu nombreux : tout ce qui appartient à un niveau doit vivre dans la scène de ce niveau.
Note pour les outils : godot --check-only --script ne charge pas les autoloads, donc un script qui utilise un nom d'autoload signale Identifier not found: Events là-bas même s'il fonctionne normalement. Vérifiez ces scripts en exécutant la scène (voir le skill godot-verify).
class_name
class_name Player enregistre un type global, permettant à d'autres scripts d'écrire var player: Player et d'obtenir la vérification des membres. L'éditeur conserve un cache de classes globales dans .godot/ ; après avoir ajouté un class_name en dehors de l'éditeur, ouvrez l'éditeur ou exécutez godot --headless --path . --import avant de vérifier les scripts qui l'utilisent.
UIDs, fichiers .uid et déplacement de fichiers
Godot 4 référence les ressources par UID ainsi que par chemin. Les scènes et ressources stockent leur propre UID dans l'en-tête du fichier, les ressources importées dans leur fichier .import, et depuis Godot 4.4 les scripts et shaders obtiennent un fichier compagnon (player.gd.uid, water.gdshader.uid). Une référence enregistrée par l'éditeur ressemble à :
[ext_resource type="Script" uid="uid://dxxoiuob4eoum" path="res://game_manager.gd" id="1_feb5d"]
Règles :
- Ajoutez les fichiers
*.uidau contrôle de version. Ne les ajoutez pas à.gitignore. - Déplacez et renommez les fichiers dans le dock Système de fichiers de Godot lorsque c'est possible ; il met à jour les références.
- Lorsque vous déplacez un script ou un shader en dehors de Godot (shell, IDE, agent), déplacez son fichier
.uidavec lui, puis ouvrez l'éditeur ou exécutezgodot --headless --path . --importpour que le cache d'UID apprenne le nouveau chemin. Jusqu'à cette analyse, l'ancien chemin est toujours utilisé et le chargement échoue. - Si le fichier
.uidest laissé derrière, Godot génère un nouvel UID pour le script déplacé et les scènes qui référençaient l'ancien retombent sur leur chemin obsolète :WARNING: ... invalid UID: uid://... - using text path instead: res://old/path.gd, puisERROR: ... referenced non-existent resource. - Lors de l'écriture manuelle d'un
.tscn, n'inventez pas de valeursuid=. Omettez l'attribut et utilisez unpathcorrect ; l'éditeur ajoute les UIDs lors de la prochaine sauvegarde de la scène. - Une scène Godot 4 écrite manuellement commence par
[gd_scene format=3]et référence les ressources par un identifiant de chaîne :[ext_resource type="Script" path="res://main.gd" id="1_main"], puisscript = ExtResource("1_main")sur le nœud. Les nœuds enfants ont besoin deparent="."ou d'un chemin depuis la racine. Godot 4.7 écrit aussiunique_id=sur les nœuds ; omettez-le manuellement. load("uid://...")etpreload("uid://...")acceptent les chaînes d'UID. Copiez un UID depuis le menu contextuel du dock Système de fichiers ;ResourceUID.id_to_text(ResourceLoader.get_resource_uid(path))le renvoie depuis le code.
Erreurs courantes
- Remonter avec
get_parent().get_parent()ou des chemins absolus comme/root/Main/Player. Exportez une référence, utilisez un groupe ou émettez un signal. - Utiliser un nœud dans
_init()ou avant qu'il ne soit entré dans l'arbre. - Coder en dur des chemins
res://vers des scènes dans plusieurs scripts au lieu d'exporter unPackedScene. - Déplacer des fichiers
.gdsans leurs fichiers.uid, ou ignorer*.uiddans git. - Tout transformer en autoload par commodité.