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...
Formato dei file TSCN
Il formato di file TSCN (text scene) rappresenta un singolo albero di scena all'interno di Godot. A differenza dei file binari SCN, i file TSCN hanno il vantaggio di essere per lo più leggibili in chiaro, nonché facili da gestire per i sistemi di controllo versioni.
Il formato file ESCN ("Exported SCeNe") è identico al formato file TSCN, ma è utilizzato per indicare a Godot che il file è stato esportato da un altro programma e non deve essere modificato dall'utente all'interno di Godot. A differenza dei file SCN e TSCN, durante l'importazione, i file ESCN vengono compilati in file SCN binari, memorizzati nella cartella .godot/imported/. Ciò riduce le dimensioni dei dati e velocizza il caricamento, poiché i formati binari sono più rapidi da caricare rispetto ai formati testuali.
Per rendere i file più compatti, le proprietà uguali al valore predefinito non sono memorizzate nei file di scena/risorsa. È possibile scriverle manualmente, ma verranno eliminate al momento del salvataggio del file.
Per chi è interessato a una descrizione completa, l'analisi è gestita nel file resource_format_text.cpp nella classe ResourceFormatLoaderText.
Nota
I formati dei file di scena e di risorse sono cambiati in modo considerevole in Godot 4, con l'introduzione di UID basati su stringa per sostituire gli ID interi incrementali.
Anche i dati di mesh, scheletro e animazione sono memorizzati diversamente rispetto a Godot 3. È possibile leggere alcuni dei cambiamenti in questo articolo: Animation data rework for 4.0
Le scene e le risorse salvate con Godot 4.x contengono format=3 nella loro intestazione, mentre Godot 3.x utilizza invece format=2.
Struttura dei file
Il file TSCN è suddiviso in cinque sezioni principali:
Descrittore del file
Risorse esterne
Risorse interne
Nodi
Connessioni
Il descrittore del file ha il formato [gd_scene format=3 uid="uid://cecaux1sm7mo0"] e dovrebbe essere la prima voce nel file. Si noti che le scene salvate prima di Godot 4.6 avranno anche un attributo load_steps=<int> nel descrittore del file. Questo attributo è ora deprecato e dovrebbe essere ignorato se presente.
uid è un identificatore univoco di tipo stringa che rappresenta la scena. È utilizzato dal motore per tenere traccia dei file che vengono spostati, anche quando l'editor è chiuso. Gli script possono anche caricare risorse basate su UID attraverso il prefisso di percorso uid:// per non dipendere dai percorsi del file system. Ciò rende possibile spostare un file nel progetto, essendo comunque in grado di caricarlo senza dover modificare gli script. Godot non utilizza file esterni per tenere traccia degli ID, il che significa che non è necessaria alcun posto centrale per memorizzare i metadati all'interno del progetto. Consultare questa richiesta di pull per informazioni dettagliate.
Queste sezioni dovrebbero apparire in ordine, ma può essere difficile distinguerle. L'unica differenza tra loro è il primo elemento nell'intestazione di tutti gli elementi della sezione. Ad esempio, l'intestazione di tutte le risorse esterne dovrebbe iniziare con [ext_resource ...].
Un file TSCN può contenere commenti su una sola riga che iniziano con un punto e virgola (;). Tuttavia, i commenti saranno eliminati al salvataggio della risorsa tramite l'editor Godot. Gli spazi vuoti all'interno di un file TSCN non importano (tranne che all'interno delle stringhe), ma gli spazi vuoti superflui saranno eliminati al salvataggio.
Voci all'interno del file
Un'intestazione appare così: [<resource_type> key1=value1 key2=value2 key3=value3 ...] dove resource_type è uno dei seguenti:
ext_resourcesub_resourcenodeconnection
Sotto ogni intestazione si trovano zero o più coppie chiave = valore. I valori possono essere tipi di dati complessi come array, trasformazioni, colori e così via. Ad esempio, un Node3D appare così:
[node name="Cube" type="Node3D" unique_id=224283918]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 2, 3)
L'albero di scene
L'albero di scene è composto da... nodi! L'intestazione di ogni nodo è composta dal suo nome, dal genitore, un ID univoco (usato per tenere traccia dei nodi anche se sono spostati o rinominati) e, il più delle volte, da un tipo. Ad esempio: [node name="PlayerCamera" type="Camera" parent="Player/Head" unique_id=1697057368]
Si noti che unique_id è presente solo nelle scene salvate con Godot 4.6 o successivo. Pertanto, non è garantito che sia presente.
Altre parole chiave valide includono:
instance
instance_placeholder
owner
index(imposta l'ordine di apparizione nell'albero; se assenti, i nodi ereditati avranno la precedenza su quelli semplici)
groups
node_paths(elenca i nomi delle proprietà esportate come tipo Node, ma referenziate come NodePath nel file)
Il primo nodo del file, che è anche la radice della scena, non deve avere la voce parent="Path/To/Node" nella sua intestazione. Tutti i file di scena devono avere esattamente una radice della scena. Se non, Godot non riuscirà a importare il file. Il percorso del genitore degli altri nodi deve essere assoluto, ma non deve contenere il nome della radice della scena. Se il nodo è un figlio diretto della radice della scena, il percorso deve essere ".". Ecco un esempio di albero di scena (ma senza alcun contenuto di nodo):
[node name="Player" type="Node3D" unique_id=1155673912] ; The scene root
[node name="Arm" type="Node3D" parent="." unique_id=1010797352] ; Parented to the scene root
[node name="Hand" type="Node3D" parent="Arm" unique_id=536436825] ; Child of "Arm"
[node name="Finger" type="Node3D" parent="Arm/Hand" unique_id=1732647084] ; Child of "Hand"
Suggerimento
Per rendere più chiara la struttura del file, è possibile salvare un file con un qualsiasi nodo o risorsa e poi ispezionarlo manualmente in un editor esterno. È anche possibile apportare modifiche graduali nell'editor Godot e tenere aperto un editor di testo esterno sul file .tscn o .tres con il ricaricamento automatico abilitato per vedere cosa cambia.
Ecco un esempio di una scena contenente una palla basata su RigidBody3D con collisione, nodi visivi (mesh + luce) e una telecamera come figlio di un RigidBody3D:
[gd_scene format=3 uid="uid://cecaux1sm7mo0"]
[sub_resource type="SphereShape3D" id="SphereShape3D_tj6p1"]
[sub_resource type="SphereMesh" id="SphereMesh_4w3ye"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_k54se"]
albedo_color = Color(1, 0.639216, 0.309804, 1)
[node name="Ball" type="RigidBody3D" unique_id=1358867382]
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1279975976]
shape = SubResource("SphereShape3D_tj6p1")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=558852834]
mesh = SubResource("SphereMesh_4w3ye")
surface_material_override/0 = SubResource("StandardMaterial3D_k54se")
[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=1581292810 node_paths=PackedStringArray("follow_node")]
light_color = Color(1, 0.698039, 0.321569, 1)
omni_range = 10.0
follow_node = NodePath("..")
[node name="Camera3D" type="Camera3D" parent="." unique_id=795715540]
transform = Transform3D(1, 0, 0, 0, 0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 1, 3)
NodePath
Una struttura ad albero non è sufficiente a rappresentare l'intera scena. Godot utilizza la struttura NodePath(Path/To/Node) per fare riferimento a un altro nodo o attributo del nodo in qualsiasi punto dell'albero di scena. I percorsi sono relativi al nodo attuale, con NodePath(".") che punta al nodo attuale e NodePath("") che non punta ad alcun nodo.
Ad esempio, MeshInstance3D utilizza NodePath() per puntare al suo scheletro. Allo stesso modo, le tracce di animazione utilizzano NodePath() per puntare alle proprietà dei nodi da animare.
NodePath può anche puntare a una proprietà utilizzando il suffisso :property_name e persino a una componente specifica per i tipi vettore, trasformazione e colore. Ciò è utilizzato dalle risorse Animation per puntare a proprietà specifiche da animare. Ad esempio, NodePath("MeshInstance3D:scale.x") punta al componente x della proprietà Vector3 scale in MeshInstance3D.
Ad esempio, la proprietà skeleton nel nodo MeshInstance3D denominato mesh punta al suo genitore, Armature01:
[node name="mesh" type="MeshInstance3D" parent="Armature01" unique_id=1638249225]
skeleton = NodePath("..")
Skeleton3D
Il nodo Skeleton3D eredita il nodo Node3D, ma può anche contenere un elenco di ossa descritte da coppie chiave-valore nel formato bones/<id>/<attributo> = valore. Gli attributi delle ossa sono costituiti da:
position: Vector3rotation: Quaternionscale: Vector3
Questi attributi sono tutti facoltativi. Ad esempio, un osso può definire solo position o rotation senza definire le altre proprietà.
Ecco un esempio di un nodo scheletro con due ossa:
[node name="Skeleton3D" type="Skeleton3D" parent="PlayerModel/Robot_Skeleton" index="0" unique_id=542985694]
bones/1/position = Vector3(0.114471, 2.19771, -0.197845)
bones/1/rotation = Quaternion(0.191422, -0.0471201, -0.00831942, 0.980341)
bones/2/position = Vector3(-2.59096e-05, 0.236002, 0.000347473)
bones/2/rotation = Quaternion(-0.0580488, 0.0310587, -0.0085914, 0.997794)
bones/2/scale = Vector3(0.9276, 0.9276, 0.9276)
BoneAttachment3D
Il nodo BoneAttachment3D è un nodo intermedio per descrivere un nodo genitore di un singolo osso in un nodo Skeleton. BoneAttachment ha una proprietà bone_name = "nome dell'osso", così come una proprietà per l'indice dell'osso corrispondente.
Un esempio di un nodo Marker3D come figlio di un osso in Skeleton:
[node name="GunBone" type="BoneAttachment3D" parent="PlayerModel/Robot_Skeleton/Skeleton3D" index="5" unique_id=63481392]
transform = Transform3D(0.333531, 0.128981, -0.933896, 0.567174, 0.763886, 0.308015, 0.753209, -0.632331, 0.181604, -0.323915, 1.07098, 0.0497144)
bone_name = "hand.R"
bone_idx = 55
[node name="ShootFrom" type="Marker3D" parent="PlayerModel/Robot_Skeleton/Skeleton3D/GunBone" unique_id=679926736]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)
AnimationPlayer
Il nodo AnimationPlayer funziona con una o più librerie di animazione memorizzate nelle risorse AnimationLibrary. Una libreria di animazione è una raccolta di singole risorse Animation, la cui struttura è documentata qui.
La separazione tra le animazioni stesse e le librerie di animazione è stata effettuata in Godot 4, affinché le animazioni si possano importare separatamente dalle mesh 3D, il che è una procedura comune nei software di animazione 3D. Consultare la richiesta di pull originale per i dettagli.
Se il nome della libreria è vuoto, funge da sorgente univoca delle animazioni per questo AnimationPlayer. Ciò permette di utilizzare <animation_name> direttamente per riprodurre le animazioni da codice. Se si assegna un nome alla libreria, è necessario riprodurla come <library_name>/<animation_name>. Ciò garantisce la retrocompatibilità e mantiene il flusso di lavoro esistente se non si desidera usare più di una libreria di animazione.
Risorse
Le risorse sono gli elementi che compongono i nodi. Ad esempio, un nodo MeshInstance3D avrà una risorsa ArrayMesh associata. La risorsa ArrayMesh può essere interna o esterna al file TSCN.
I riferimenti alle risorse sono gestiti da ID univoci di tipo stringa nell'intestazione della risorsa. Questo è diverso dalla proprietà uid, contenuta anche in ogni risorsa esterna (ma non nelle sotto-risorse).
Le risorse esterne e interne sono indicate rispettivamente con ExtResource("id") e SubResource("id"). Poiché esistono metodi diversi per fare riferimento alle risorse interne ed esterne, è possibile avere lo stesso ID sia per una risorsa interna sia per una risorsa esterna.
Ad esempio, per fare riferimento alla risorsa [ext_resource type="Material" uid="uid://c4cp0al3ljsjv" path="res://material.tres" id="1_7bt6s"], si userebbe ExtResource("1_7bt6s").
Risorse esterne
Le risorse esterne sono collegamenti a risorse non contenute nel file TSCN stesso. Una risorsa esterna è composta da un percorso, un tipo, un UID (utilizzato per mappare la posizione del file system a un identificatore univoco) e un ID (utilizzato per fare riferimento alla risorsa nel file di scena).
Godot genera sempre percorsi assoluti relativi alla cartella di risorse, quindi preceduti dal prefisso res://, ma sono validi anche i percorsi relativi alla posizione del file TSCN.
Alcuni esempi di risorse esterne sono:
[ext_resource type="Texture2D" uid="uid://ccbm14ebjmpy1" path="res://gradient.tres" id="2_eorut"]
[ext_resource type="Material" uid="uid://c4cp0al3ljsjv" path="material.tres" id="1_7bt6s"]
Come i file TSCN, un file TRES può contenere commenti su una sola riga che iniziano con un punto e virgola (;). Tuttavia, i commenti saranno eliminati al salvataggio della risorsa tramite l'editor Godot. Gli spazi vuoti all'interno di un file TRES non importano (tranne che all'interno delle stringhe), ma gli spazi vuoti superflui saranno eliminati al salvataggio.
Risorse interne
Un file TSCN può contenere mesh, materiali e altri dati. Questi sono contenuti nella sezione risorse interne del file. L'intestazione di una risorsa interna è simile a quella delle risorse esterne, eccetto che non ha un percorso. Anche le risorse interne hanno coppie chiave=valore sotto ogni intestazione. Ad esempio, una forma di collisione a capsula ha questo appare così:
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_fdxgg"]
radius = 1.0
height = 3.0
Alcune risorse interne contengono collegamenti ad altre risorse interne (ad esempio, una mesh con un materiale). In questo caso, la risorsa riferita deve apparire prima del riferimento ad essa. Ciò significa che l'ordine è importante nella sezione delle risorse interne del file.
ArrayMesh
Un ArrayMesh è costituito da diverse superfici contenute nell'array _surfaces (notare il trattino basso iniziale). I dati di ogni superficie sono memorizzati in un dizionario con le seguenti chiavi:
aabb: La bounding box allineata agli assi calcolata per la visibilità.attribute_data: dati degli attributi dei vertici, come normali, tangenti, colori dei vertici, UV1, UV2 e dati personalizzati dei vertici.bone_aabbs: La bounding box allineata agli assi di ogni osso per la visibilità.format: formato del buffer della superficie.index_count: il numero di indici nella superficie. Deve corrispondere alla dimensione diindex_data.index_data: i dati di indice, che determinano quali vertici davertex_datasono disegnati.lods: variazioni del livello di dettaglio, memorizzate come array. Ogni livello LOD rappresenta due valori nell'array. Il primo valore è la percentuale di spazio dello schermo per cui il livello LOD è più adatto (lunghezza del bordo); il secondo valore è l'elenco di indici da disegnare per il livello LOD specificato.material: il materiale utilizzato per disegnare la superficie.name: il nome della superficie. Si può utilizzare negli script e viene importato da file DCC 3D.primitive: tipo di primitiva della superficie, corrispondente all'enumerazione di GodotMesh.PrimitiveType.0= punti,1= linee,2= striscia di linee,3= triangoli (i più comuni),4= striscia di triangoli.skin_data: dati di peso delle ossa.vertex_count: numero di vertici nella superficie. Deve corrispondere alla dimensione divertex_data.vertex_data: dati sulla posizione dei vertici.
Ecco un esempio di un ArrayMesh salvato nel proprio file .tres. Alcuni campi sono stati abbreviati con ... per convenienza:
[gd_resource type="ArrayMesh" format=3 uid="uid://dww8o7hsqrhx5"]
[ext_resource type="Material" path="res://player/model/playerobot.tres" id="1_r3bjq"]
[resource]
resource_name = "player_Sphere_016"
_surfaces = [{
"aabb": AABB(-0.207928, 1.21409, -0.14545, 0.415856, 0.226569, 0.223374),
"attribute_data": PackedByteArray(63, 121, ..., 117, 63),
"bone_aabbs": [AABB(0, 0, 0, -1, -1, -1), ..., AABB(-0.207928, 1.21409, -0.14545, 0.134291, 0.226569, 0.223374)],
"format": 7191,
"index_count": 1224,
"index_data": PackedByteArray(30, 0, ..., 150, 4),
"lods": [0.0382013, PackedByteArray(33, 1, ..., 150, 4)],
"material": ExtResource("1_r3bjq"),
"name": "playerobot",
"primitive": 3,
"skin_data": PackedByteArray(15, 0, ..., 0, 0),
"vertex_count": 1250,
"vertex_data": PackedByteArray(196, 169, ..., 11, 38)
}]
blend_shape_mode = 0
Animazione
Ogni animazione ha le seguenti proprietà:
length: la durata dell'animazione in secondi. Si noti che i fotogrammi chiave potrebbero essere posizionati al di fuori dell'intervallo[0; length], ma potrebbero non avere alcun effetto a seconda della modalità di interpolazione scelta.loop_mode:0= nessun ciclo,1= ciclo avvolgente,2= ciclo limitato.step: la dimensione del passo da utilizzare quando si modifica questa animazione nell'editor. È utilizzata solo nell'editor; non influisce in alcun modo sulla riproduzione dell'animazione.
Ogni traccia è descritta da un elenco di coppie chiave-valore nel formato tracks/<id>/<attribute>. Ogni traccia include:
type: il tipo di traccia. Definisce quali proprietà possono essere animate da questa traccia e come saranno esposte all'utente nell'editor. I tipi validi sonovalue(traccia di proprietà generica),position_3d,rotation_3d,scale_3d,blend_shape(tracce di animazione 3D ottimizzate),method(tracce di chiamata metodo),bezier(tracce di curva di Bézier),audio(tracce di riproduzione audio),animation(tracce che riproducono altre animazioni).imported:truese la traccia è stata creata da una scena 3D importata,falsese è stata creata manualmente dall'utente nell'editor Godot o tramite uno script.enabled:truese la traccia è attiva,falsese è stata disabilitata nell'editor.path: percorso verso la proprietà del nodo che sarà influenzata dalla traccia. La proprietà è scritta dopo il percorso del nodo con un separatore:.interp: la modalità di interpolazione da utilizzare.0= più vicino,1= lineare,2= cubico,3= angolo lineare,4= angolo cubico.loop_wrap:truese la traccia è progettata per avvolgersi quando l'animazione è in ripetizione,falsese la traccia si limita al primo/ultimo fotogramma chiave.keys: i valori della traccia di animazione. La struttura di questo attributo dipende datype.
Ecco una scena contenente un AnimationPlayer che riduce le dimensioni di un cubo nel tempo utilizzando una traccia di proprietà generica. Il flusso di lavoro per AnimationLibrary non è stato utilizzato, quindi la libreria di animazioni ha un nome vuoto (ma all'animazione è comunque assegnato il nome scale_down). Si noti che la traccia RESET non è stata creata in questo AnimationPlayer per brevità:
[gd_scene format=3 uid="uid://cdyt3nktp6y6"]
[sub_resource type="Animation" id="Animation_r2qdp"]
resource_name = "scale_down"
length = 1.5
loop_mode = 2
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Box:scale")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(0, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_4qx36"]
_data = {
"scale_down": SubResource("Animation_r2qdp")
}
[sub_resource type="BoxMesh" id="BoxMesh_u688r"]
[node name="Node3D" type="Node3D" unique_id=2076735200]
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=2139773137]
autoplay = "scale_down"
libraries = {
"": SubResource("AnimationLibrary_4qx36")
}
[node name="Box" type="MeshInstance3D" parent="." unique_id=711004519]
mesh = SubResource("BoxMesh_u688r")
Per le tracce di proprietà generiche value, keys è un dizionario contenente 3 array con posizioni in times (PackedFloat32Array), valori di easing in transitions (PackedFloat32Array) e valori in values (Array). Esiste un'ulteriore proprietà update, che è un intero con i valori 0 = continuo, 1 = discreto, 2 = cattura.
Ecco una seconda risorsa animazione che utilizza le tracce Posizione 3D e Rotazione 3D. Queste tracce (oltre alla traccia Scala 3D) sostituiscono le tracce Trasformazione di Godot 3. Sono ottimizzate per una riproduzione rapida e si possono facoltativamente comprimere.
Lo svantaggio di questi tipi di traccia ottimizzati è che non possono utilizzare valori di easing personalizzati. Invece, tutti i fotogrammi chiave utilizzano l'interpolazione lineare. Detto ciò, è comunque possibile scegliere di utilizzare l'interpolazione più vicina o cubica per tutti i fotogrammi chiave di una determinata traccia, modificando la modalità di interpolazione della traccia.
[sub_resource type="Animation" id="Animation_r2qdp"]
resource_name = "move_and_rotate"
length = 1.5
loop_mode = 2
step = 0.05
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Box")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1.5, 1, 1.5, 1, 0)
tracks/1/type = "rotation_3d"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Box")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = PackedFloat32Array(0, 1, 0.211, -0.047, 0.211, 0.953, 1.5, 1, 0.005, 0.976, -0.216, 0.022)
Per le tracce di posizione, rotazione e scala 3D, keys è un PackedFloat32Array con tutti i valori memorizzati in una sequenza.
Nella guida visiva in seguito, T è il tempo del fotogramma chiave in secondi dall'inizio dell'animazione, E è la transizione del fotogramma chiave (attualmente sempre 1). Per le tracce di posizione e scala 3D, X, Y, Z sono le coordinate del vettore 3D. Per le tracce di rotazione 3D, X, Y, Z e W sono le coordinate del quaternione.
# For 3D position and scale, which use Vector3:
tracks/<id>/keys = PackedFloat32Array(T, E, X, Y, Z, T, E, X, Y, Z, ...)
# For 3D rotation, which use Quaternion:
tracks/<id>/keys = PackedFloat32Array(T, E, X, Y, Z, W, T, E, X, Y, Z, W, ...)