Up to date

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

TSCN Dateiformat

Das TSCN-Dateiformat (Text Scene) stellt einen einzelnen Szenenbaum innerhalb von Godot dar. Im Gegensatz zu binären SCN-Dateien haben TSCN-Dateien den Vorteil, dass sie größtenteils für Menschen lesbar und für Versionskontrollsysteme leicht zu verwalten sind.

Das ESCN-Dateiformat (exportierte Szene) ist identisch mit dem TSCN-Dateiformat, wird aber verwendet, um Godot anzuzeigen, dass die Datei aus einem anderen Programm exportiert wurde und vom Benutzer nicht innerhalb von Godot bearbeitet werden sollte. Im Gegensatz zu SCN- und TSCN-Dateien werden ESCN-Dateien beim Import zu binären SCN-Dateien kompiliert, die im Ordner .godot/imported/ gespeichert werden. Dadurch wird die Datengröße verringert und das Laden beschleunigt, da Binärformate im Vergleich zu textbasierten Formaten schneller geladen werden können.

Um die Dateien kompakter zu machen, werden Propertys, die dem Defaultwert entsprechen, nicht in Szenen-/Ressourcendateien gespeichert. Es ist möglich, sie manuell zu schreiben, aber sie werden beim Speichern der Datei verworfen.

Für diejenigen, die eine vollständige Beschreibung suchen, wird das Parsen in der Datei resource_format_text.cpp in der Klasse ResourceFormatLoaderText behandelt.

Bemerkung

Die Formate der Szenen- und Ressourcendateien haben sich in Godot 4 mit der Einführung von stringbasierten UIDs, den Nachfolgern der inkrementellen Integer-IDs, erheblich geändert.

Mesh-, Skelett- und Animationsdaten werden im Vergleich zu Godot 3 auch anders gespeichert. Sie können einige der Änderungen in diesem Artikel nachlesen: Animationsdaten-Überarbeitung für 4.0

Szenen und Ressourcen, die mit Godot 4.x gespeichert werden, enthalten format=3 in ihrem Header, während Godot 3.x stattdessen format=2 verwendet.

Dateistruktur

Es gibt 5 Hauptblöcke innerhalb der TSCN Datei:

  1. Datei-Deskriptor

  2. Externe Quellen

  3. Interne Quellen

  4. Nodes

  5. Verbindungen

Der Dateideskriptor sieht aus wie [gd_scene load_steps=4 format=3 uid="uid://cecaux1sm7mo0"] und sollte der erste Eintrag in der Datei sein. Der Parameter load_steps ist gleich der Gesamtmenge der Ressourcen (intern und extern) plus eins (für die Datei selbst). Wenn die Datei keine Ressourcen hat, wird load_steps weggelassen. Die Engine wird die Datei trotzdem korrekt laden, wenn load_steps nicht korrekt ist, aber dies wird sich auf die Ladebalken und jedes andere Stück Code auswirken, das auf diesen Wert angewiesen ist.

uid ist ein eindeutiger stringbasierter Bezeichner, der die Szene repräsentiert. Sie wird von der Engine verwendet, um Dateien zu tracken, die verschoben werden, auch wenn der Editor geschlossen ist. Skripte können UID-basierte Ressourcen auch mit dem uid:// Pfadpräfix laden, um von Dateisystempfade unabhängig zu sein. Dadurch ist es möglich, eine Datei im Projekt zu verschieben, sie aber trotzdem in Skripten zu laden, ohne das Skript ändern zu müssen. Godot verwendet keine externen Dateien, um die IDs zu verfolgen, was bedeutet, dass kein zentraler Speicherort für Metadaten innerhalb des Projekts erforderlich ist. Siehe diesen Pull Request für detaillierte Informationen.

Diese Abschnitte sollten der Reihe nach erscheinen, aber sie sind möglicherweise schwer voneinader zu unterscheiden. Der einzige Unterschied zwischen ihnen ist das erste Element in der Überschrift für alle Elemente des Abschnitts. Zum Beispiel sollte die Überschrift aller externen Ressourcen mit [ext_resource ...] beginnen.

Eine TSCN-Datei kann einzeilige Kommentare enthalten, die mit einem Semikolon (;) beginnen. Kommentare werden jedoch beim Speichern der Datei mit dem Godot-Editor verworfen. Leerzeichen innerhalb einer TSCN-Datei sind nicht von Bedeutung (außer innerhalb von Zeichenketten), aber überflüssige Leerzeichen werden beim Speichern der Datei verworfen.

Einträge innerhalb der Datei

Eine Überschrift sieht aus wie [<resource_type> key1=value1 key2=value2 key3=value3 ...], wobei resource_type eine der folgenden Strings ist:

  • ext_resource

  • sub_resource

  • node

  • connection

Unter jeder Überschrift stehen null oder mehr key = value-Paare. Die Werte können komplexe Datentypen sein, wie Arrays, Transforms, Farben und so weiter. Ein Node3D sieht zum Beispiel so aus:

[node name="Cube" type="Node3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 2, 3)

Der Szenenbaum

Der Szenenbaum besteht aus... Nodes! Die Überschrift eines jeden Nodes besteht aus dem Namen, dem Parent-Element und (meistens) einem Typ. Zum Beispiel: [node name="PlayerCamera" type="Camera" parent="Player/Head"]

Andere gültige Schlüsselwörter sind unter anderem:

  • instance

  • instance_placeholder

  • owner

  • index (legt die Reihenfolge des Auftretens im Baum fest; wenn nicht vorhanden, haben vererbte Nodes Vorrang vor einfachen)

  • groups

Der erste Node in der Datei, der auch der Szenen-Root ist, darf nicht einen parent="Path/To/Node"-Eintrag in seiner Überschrift haben. Alle Szenendateien sollten genau einen Szenen-Root haben. Wenn dies nicht der Fall ist, wird Godot die Datei nicht importieren können. Der übergeordnete Pfad der anderen Nodes sollte absolut sein, aber nicht den Namen des Szenen-Roots enthalten. Wenn der Node ein direktes Child des Szenen-Roots ist, sollte der Pfad "." sein. Hier ist ein Beispiel für einen Szenenbaum (allerdings ohne jeglichen Node-Inhalt):

[node name="Player" type="Node3D"]                    ; The scene root
[node name="Arm" type="Node3D" parent="."]            ; Parented to the scene root
[node name="Hand" type="Node3D" parent="Arm"]         ; Child of "Arm"
[node name="Finger" type="Node3D" parent="Arm/Hand"]  ; Child of "Hand"

Tipp

Um die Dateistruktur leichter zu verstehen, können Sie eine Datei mit einem bestimmten Node oder einer bestimmten Ressource speichern und sie dann selbst in einem externen Editor ansehen. Sie können auch schrittweise Änderungen im Godot-Editor vornehmen und einen externen Texteditor für die Datei .tscn oder .tres mit aktiviertem automatischen Neuladen geöffnet lassen, um die Änderungen zu sehen.

Hier ist ein Beispiel für eine Szene, die einen RigidBody3D-basierten Ball mit Kollisionen, Visuals (Mesh + Licht) und eine dem RigidBody3D übergeordnete Kamera enthält:

[gd_scene load_steps=4 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"]

[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_tj6p1")

[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
mesh = SubResource("SphereMesh_4w3ye")
surface_material_override/0 = SubResource("StandardMaterial3D_k54se")

[node name="OmniLight3D" type="OmniLight3D" parent="."]
light_color = Color(1, 0.698039, 0.321569, 1)
omni_range = 10.0

[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 1, 3)

NodePath

Eine Baumstruktur reicht nicht aus, um die gesamte Szene darzustellen. Godot verwendet eine NodePath(Path/To/Node)-Struktur, um auf einen anderen Node oder ein Attribut des Nodes irgendwo im Szenenbaum zu verweisen. Pfade sind relativ zum aktuellen Node, wobei NodePath(".") auf den aktuellen Node und NodePath("") auf gar keinen Node zeigt.

Zum Beispiel benutzt MeshInstance3D NodePath(), um auf sein Skelett zu zeigen. Ebenso benutzen Animation-Tracks NodePath(), um auf Node-Propertys zu zeigen, die animiert werden sollen.

NodePath kann auch auf eine Property mit dem Suffix :property_name verweisen und sogar auf eine bestimmte Komponente für Vektor-, Transform- und Farbtypen. Dies wird von Animationsressourcen verwendet, um auf bestimmte Propertys zu zeigen, die animiert werden sollen. Zum Beispiel zeigt NodePath("MeshInstance3D:scale.x") auf die x-Property der scale-Vector3-Property in MeshInstance3D.

Zum Beispiel zeigt die Property Skelett im MeshInstance3D-Nodes namens Mesh auf seinen Parent, Armature01:

[node name="mesh" type="MeshInstance3D" parent="Armature01"]
skeleton = NodePath("..")

Skeleton3D

Der Skeleton3D-Node erbt den Node3D-Node, kann aber auch eine Liste von Knochen haben, die in Schlüssel-Wert-Paaren im Format bones/<id>/<attribute> = value beschrieben werden. Die Knochen-Attribute bestehen aus:

  • position: Vector3

  • rotation: Quaternion

  • scale: Vector3

Diese Attribute sind alle optional. Zum Beispiel kann ein Knochen nur Position oder Rotation definieren, ohne die anderen Propertys zu definieren.

Hier ist ein Beispiel für einen Skelett-Node mit zwei Knochen:

[node name="Skeleton3D" type="Skeleton3D" parent="PlayerModel/Robot_Skeleton" index="0"]
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

Der Node BoneAttachment3D ist ein Zwischen-Node zur Beschreibung eines Nodes, der einem einzelnen Knochen in einem Skelett-Node übergeordnet ist. Das BoneAttachment hat eine Property bone_name = "Name des Knochens", sowie eine Property für den passenden Knochen-Index.

Ein Beispiel für einen Marker3D-Node, der einem Knochen im Skelett übergeordnet ist:

[node name="GunBone" type="BoneAttachment3D" parent="PlayerModel/Robot_Skeleton/Skeleton3D" index="5"]
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"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0)

AnimationPlayer

Der AnimationPlayer-Node arbeitet mit einer oder mehreren Animationsbibliotheken, die in AnimationLibrary-Ressourcen gespeichert sind. Eine Animationsbibliothek ist eine Sammlung von einzelnen Animation-Ressourcen, deren Struktur hier dokumentiert ist.

Diese Trennung zwischen Animationen selbst und Animationsbibliotheken wurde in Godot 4 vorgenommen, so dass Animationen getrennt von 3D-Meshes importiert werden können, was ein üblicher Workflow in 3D-Animationssoftware ist. Siehe den ursprünglichen Pull Request für Details.

Wenn der Bibliotheksname leer ist, dann fungiert er als die einzige Quelle für Animationen für diesen AnimationPlayer. Dies erlaubt die direkte Verwendung von <Animation_name>, um Animationen aus einem Skript abzuspielen. Wenn Sie die Bibliothek benennen, müssen Sie sie als <bibliothek_name>/<animation_name> abspielen. Dies stellt die Rückwärtskompatibilität sicher und behält den bestehenden Workflow bei, wenn Sie nicht mehrere Animationsbibliotheken verwenden wollen.

Ressourcen

Ressourcen sind Komponenten, aus denen die Nodes bestehen. Zum Beispiel hat ein MeshInstance3D-Node eine zugehörige ArrayMesh-Ressource. Die ArrayMesh-Ressource kann entweder intern oder extern in der TSCN-Datei sein.

Verweise auf die Ressourcen werden durch eindeutige, auf Zeichenketten basierende IDs in der Überschrift der Ressource behandelt. Dies unterscheidet sich von der Property uid, die jede externe Ressource ebenfalls hat (Unterressourcen jedoch nicht).

Auf externe Ressourcen und interne Ressourcen wird mit ExtResource("id") bzw. SubResource("id") verwiesen. Da es unterschiedliche Methoden gibt, um auf interne und externe Ressourcen zu verweisen, können Sie dieselbe ID für eine interne und eine externe Ressource haben.

Um zum Beispiel auf die Ressource [ext_resource type="Material" uid="uid://c4cp0al3ljsjv" path="res://material.tres" id="1_7bt6s"] zu verweisen, würden Sie ExtResource("1_7bt6s") verwenden.

Externe Quellen

Externe Ressourcen sind Links zu Ressourcen, die nicht in der TSCN-Datei selbst enthalten sind. Eine externe Ressource besteht aus einem Pfad, einem Typ, einer UID (die dazu dient, den Speicherort im Dateisystem einem eindeutigen Bezeichner zuzuordnen) und einer ID (die dazu dient, in der Szenendatei auf die Ressource zu verweisen).

Godot erzeugt immer absolute Pfade ausgehend vom Stammverzeichnis und zeigt dieses als res:// an, aber Pfade relativ zu TSCN Datei-Verzeichnisssen sind ebenso möglich.

Einige Beispiele externer Quellen sind:

[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"]

Wie TSCN-Dateien kann auch eine TRES-Datei einzeilige Kommentare enthalten, die mit einem Semikolon (;) beginnen. Beim Speichern der Ressource mit dem Godot-Editor werden die Kommentare jedoch verworfen. Whitespace innerhalb einer TRES-Datei ist nicht von Bedeutung (außer innerhalb von Zeichenketten), aber überflüssiger Whitespace wird beim Speichern der Datei verworfen.

Interne Quellen

Eine TSCN-Datei kann Meshes, Materialien und andere Daten enthalten. Diese sind im Abschnitt interne Ressourcen der Datei enthalten. Die Überschrift für eine interne Ressource sieht ähnlich aus wie die von externen Ressourcen, mit dem Unterschied, dass sie keinen Pfad hat. Interne Ressourcen haben auch key=value-Paare unter jeder Überschrift. Eine Capsule-Collision Shape sieht zum Beispiel so aus:

[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_fdxgg"]
radius = 1.0
height = 3.0

Einige interne Ressourcen enthalten Verweise auf andere interne Ressourcen (z.B. ein Mesh, das ein Material hat). In diesem Fall muss die verweisende Ressource vor dem Verweis auf sie erscheinen. Das bedeutet, dass die Reihenfolge im Abschnitt "Interne Ressourcen" der Datei wichtig ist.

ArrayMesh

Ein ArrayMesh besteht aus mehreren Flächen, die in dem Array _surfaces enthalten sind (beachten Sie den Unterstrich am Anfang). Die Daten jeder Oberfläche werden in einem Dictionary mit den folgenden Keys gespeichert:

  • aabb: Die berechnete an den Achsen ausgerichtete Bounding Box für die Sichtbarkeit. Mesh.PrimitiveType Godot enum. 0 = Punkte, 1 = Linien, 2 = Linienstreifen, 3 = Dreiecke (am häufigsten), 4 = Dreiecksstreifen.

  • attribute_data: Vertex-Attributdaten, wie Normalen, Tangenten, Vertexfarben, UV1, UV2 und benutzerdefinierte Vertexdaten.

  • bone_aabbs: Die an den Achsen ausgerichtete Bounding Box jedes Bones für die Sichtbarkeit.

  • format: Das Bufferformat der Oberfläche.

  • index_count: Die Anzahl der Indizes in der Oberfläche. Sie muss mit der Größe von index_data übereinstimmen.

  • index_data: Die Indexdaten, die bestimmen, welche Vertices aus vertex_data gezeichnet werden.

  • lods: Level of Detail-Variationen, gespeichert als Array. Jede LOD-Stufe repräsentiert zwei Werte in dem Array. Der erste Wert ist der Prozentsatz der Bildschirmfläche, für die diese LOD-Stufe am besten geeignet ist (Kantenlänge); der zweite Wert ist die Liste der Indizes, die für die gegebene LOD-Stufe gezeichnet werden sollten.

  • material: Das Material, das beim Zeichnen der Oberfläche verwendet wird.

  • name: Der Name der Oberfläche. Dieser kann in Skripten verwendet werden und wird von 3D DCCs importiert.

  • primitive: Der primitive Typ der Oberfläche, übereinstimmend mit dem

  • skin_data: Knochengewicht-Daten.

  • vertex_count: Anzahl der Vertices in der Oberfläche. Diese muss mit der Größe von vertex_data übereinstimmen.

  • vertex_data: Vertexpositions-Daten.

Hier ist ein Beispiel für ein ArrayMesh, das in seiner eigenen .tres Datei gespeichert wurde. Einige Felder wurden der Kürze halber mit ... abgekürzt:

[gd_resource type="ArrayMesh" load_steps=2 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

Animation

Jede Animation hat die folgenden Eigenschaften:

  • length: Die Länge der Animation in Sekunden. Beachten Sie, dass Keyframes außerhalb des [0; Länge] Intervalls platziert werden können, aber je nach gewähltem Interpolationsmodus keinen Effekt haben.

  • loop_mode: 0 = kein Looping, 1 = wrap-around Looping, 2 = geclamptes Looping.

  • step: Die Schrittgröße, die bei der Bearbeitung der Animation im Editor verwendet wird. Dieser Wert wird nur im Editor verwendet; er hat keinen Einfluss auf die Wiedergabe der Animation.

Jeder Track wird durch eine Liste von Key-Value-Paaren im Format Tracks/<id>/<Attribut> beschrieben. Jeder Track enthält:

  • type: Der Typ des Tracks. Dies definiert, welche Art von Propertys von diesem Track animiert werden können, und wie sie dem Benutzer im Editor angezeigt werden. Gültige Typen sind value (Track für generische Propertys), position_3d, rotation_3d, scale_3d, blend_shape (optimierte 3D-Animations-Tracks), method (Methodenaufruf-Tracks), bezier (Bezierkurven-Tracks), audio (Audiowiedergabe-Tracks), animation (Tracks, die andere Animationen abspielen).

  • imported: true, wenn der Track aus einer importierten 3D-Szene erzeugt wurde, false, wenn er manuell vom Benutzer im Godot-Editor oder mit Hilfe eines Skripts erzeugt wurde.

  • enabled: true wenn der Track aktiv ist, false wenn er im Editor deaktiviert wurde.

  • path: Pfad zu der Node-Property, die vom Track betroffen sein wird. Die Property wird nach dem Nodepfad mit einem :-Trennzeichen geschrieben.

  • interp: Der zu verwendende Interpolationsmodus. 0 = nearest, 1 = linear, 2 = kubisch, 3 = linearer Winkel, 4 = kubischer Winkel.

  • loop_wrap: true, wenn der Track so gestaltet ist, dass er sich beim Looping der Animation mitdreht, false, wenn der Track an den ersten/letzten Keyframes geclampt wird.

  • keys: Die Werte des Animationstracks. Die Struktur dieses Attributs hängt vom Typ ab.

Hier ist eine Szene, die einen AnimationPlayer enthält, der einen Würfel mit Hilfe eines Track für generische Propertys im Laufe der Zeit verkleinert. Der AnimationLibrary-Workflow wurde nicht verwendet, daher hat die Animationsbibliothek einen leeren Namen (aber die Animation hat trotzdem einen scale_down-Namen). Beachten Sie, dass der RESET-Track in diesem AnimationPlayer der Kürze halber nicht erstellt wurde:

[gd_scene load_steps=4 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"]

[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
autoplay = "scale_down"
libraries = {
"": SubResource("AnimationLibrary_4qx36")
}

[node name="Box" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_u688r")

Für Tracks mit generischem Property-Wert ist keys ein Wörterbuch, das 3 Arrays mit Positionen in times (PackedFloat32Array), Easing-Werten in transitions (PackedFloat32Array) und Werten in values (Array) enthält. Es gibt eine zusätzliche Property update, die einen Integer mit den Werten 0 = kontinuierlich, 1 = diskret, 2 = einfangen ist.

Hier ist eine zweite Animationsressource zur Verwendung der 3D-Positions- und 3D-Rotations-Tracks. Diese Tracks (zusätzlich zum 3D Skalierungs-Track) ersetzen die Transform-Tracks von Godot 3. Sie sind für die schnelle Wiedergabe optimiert und können optional komprimiert werden.

Der Nachteil dieser optimierten Track-Typen ist, dass sie keine benutzerdefinierten Easing-Werte verwenden können. Stattdessen verwenden alle Keyframes lineare Interpolation. Dennoch können Sie für alle Keyframes eines Tracks die kubische Interpolation verwenden, indem Sie den Interpolationsmodus des Tracks ändern.

[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)

Für 3D Positions-, Rotations- und Skalierungs-Tracks ist keys ein PackedFloat32Array, in dem alle Werte in einer Sequenz gespeichert sind.

In der visuellen Anleitung unten ist T die Zeit des Keyframes in Sekunden seit dem Start der Animation, E ist der Übergang des Keyframes (derzeit immer 1). Für 3D-Positions- und Skalierungs-Tracks sind X, Y, Z die Koordinaten des Vector3. Für 3D-Rotationstracks sind X, Y, Z und W die Koordinaten des Quaternions.

# 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, ...)