TSCN-tiedostomuoto¶
The TSCN (text scene) file format represents a single scene tree inside Godot. Unlike binary SCN files, TSCN files have the advantage of being mostly human-readable and easy for version control systems to manage.
The ESCN (exported scene) file format is identical to the TSCN file format, but
is used to indicate to Godot that the file has been exported from another
program and should not be edited by the user from within Godot.
Unlike SCN and TSCN files, during import, ESCN files are compiled to binary
SCN files stored inside the .import/
folder.
This reduces the data size and speeds up loading, as binary formats are faster
to load compared to text-based formats.
Jos etsit täydellistä kuvausta, jäsennys on käsitelty tiedostossa resource_format_text.cpp, luokassa ResourceFormatLoaderText
.
Tiedoston rakenne¶
TSCN-tiedosto sisältää viisi pääosiota:
Tiedoston kuvaus
Ulkoiset resurssit
Sisäiset resurssit
Solmut
Connections
The file descriptor looks like [gd_scene load_steps=3 format=2]
and should
be the first entry in the file. The load_steps
parameter is equal to the
total amount of resources (internal and external) plus one (for the file itself).
If the file has no resources, load_steps
is omitted. The engine will
still load the file correctly if load_steps
is incorrect, but this will affect
loading bars and any other piece of code relying on that value.
Näiden osioiden tulisi esiintyä järjestyksessä, mutta niiden erottelu voi olla hankalaa. Ainoa ero niiden välillä on otsikon ensimmäinen elementti, joka on yhdistävä tekijä kaikille osion muille kohdille. Esimerkiksi kaikkien ulkoisten resurssien otsikoiden pitäisi alkaa [ext_resource .....]
.
A TSCN file may contain single-line comments starting with a semicolon (;
).
However, comments will be discarded when saving the file using the Godot editor.
Tiedoston kohdat¶
A heading looks like
[<resource_type> key=value key=value key=value ...]
where resource_type is one of:
ext_resource
sub_resource
(aliresurssi)node
(solmu)connection
(yhteys)
Below every heading comes zero or more key = value
pairs. The
values can be complex datatypes such as Arrays, Transforms, Colors, and
so on. For example, a spatial node looks like:
[node name="Cube" type="Spatial" parent="."]
transform=Transform( 1.0, 0.0, 0.0 ,0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 )
Skenepuu¶
The scene tree is made up of… nodes! The heading of each node consists of
its name, parent and (most of the time) a type. For example
[node type="Camera" name="PlayerCamera" parent="Player/Head"]
Muita avainsanoja ovat:
instance
(ilmentymä)
instance_placeholder
(ilmentymän paikanpitäjä)
owner
index
(sets the order of appearance in the tree. If absent, inherited nodes will take precedence over plain ones)
groups
Tiedoston ensimmäisessä solmussa, joka on myös skenen juurisolmu, ei tule olla parent=Path/To/Node
merkintää otsikossa. Kaikissa skenetiedostoissa tulee olla tasan yksi juurisolmu. Jos näin ei ole, Godot ei pysty tuomaan tiedostoa. Muiden solmujen yläsolmujen polkujen tulee olla absoluuttisia, eikä niiden tule sisältää skenen juuren nimeä. Jos solmut sijaitsevat suoraan skenen juuren alla, niiden polkujen tulee olla "."
. Tässä on esimerkki skenepuusta (ilman solmusisältöä):
[node name="Player" type="Spatial"] ; The scene root
[node name="Arm" parent="." type="Spatial"] ; Parented to the scene root
[node name="Hand" parent="Arm" type="Spatial"]
[node name="Finger" parent="Arm/Hand" type="Spatial"]
Similar to the internal resource, the document for each node is currently incomplete. Fortunately, it is easy to find out because you can simply save a file with that node in it. Some example nodes are:
[node type="CollisionShape" name="SphereCollision" parent="SpherePhysics"]
shape = SubResource(8)
transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , -4.371138828673793e-08 , 1.0 , -0.0 , -1.0 , -4.371138828673793e-08 ,0.0 ,0.0 ,-0.0 )
[node type="MeshInstance" name="Sphere" parent="SpherePhysics"]
mesh = SubResource(9)
transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , 1.0 , -0.0 , -0.0 , -0.0 , 1.0 ,0.0 ,0.0 ,-0.0 )
[node type="OmniLight" name="Lamp" parent="."]
light_energy = 1.0
light_specular = 1.0
transform = Transform( -0.29086464643478394 , -0.7711008191108704 , 0.5663931369781494 , -0.05518905818462372 , 0.6045246720314026 , 0.7946722507476807 , -0.9551711678504944 , 0.199883371591568 , -0.21839118003845215 ,4.076245307922363 ,7.3235554695129395 ,-1.0054539442062378 )
omni_range = 30
shadow_enabled = true
light_negative = false
light_color = Color( 1.0, 1.0, 1.0, 1.0 )
[node type="Camera" name="Camera" parent="."]
projection = 0
near = 0.10000000149011612
fov = 50
transform = Transform( 0.6859206557273865 , -0.32401350140571594 , 0.6515582203865051 , 0.0 , 0.8953956365585327 , 0.44527143239974976 , -0.7276763319969177 , -0.3054208755493164 , 0.6141703724861145 ,14.430776596069336 ,10.093015670776367 ,13.058500289916992 )
far = 100.0
NodePath¶
A tree structure is not enough to represent the whole scene. Godot uses a
NodePath(Path/To/Node)
structure to refer to another node or attribute of
the node anywhere in the scene tree. For instance, MeshInstance uses
NodePath()
to point to its skeleton. Likewise, Animation tracks use
NodePath()
to point to node properties to animate.
[node name="mesh" type="MeshInstance" parent="Armature001"]
mesh = SubResource(1)
skeleton = NodePath("..:")
[sub_resource id=3 type="Animation"]
...
tracks/0/type = "transform
tracks/0/path = NodePath("Cube:")
...
Luuranko¶
Skeleton solmu periytyy Spatial solmusta, mutta sen lisäksi sillä voi olla lista luita avain-arvo pareina muodossa bones/Id/Attribute=Value
. Luiden attribuutit ovat:
name
parent
rest
pose
enabled
bound_children
name
täytyy olla jokaisen luun ensimmäinen attribuutti.parent
on indeksi ylempään luuhun luulistassa. Sen avulla luulistasta muodostuu puu.rest
on luun muunnosmatriisi lepoasennossa.pose
on asentomatriisi; käytärest
perustana.bound_children
on listaNodePath()
rakenteita, jotka viittaavat tälle luulle kuuluviin BoneAttachment-solmuihin.
Tässä esimerkki skeleton-solmusta kahdella luulla:
[node name="Skeleton" type="Skeleton" parent="Armature001" index="0"]
bones/0/name = "Bone.001"
bones/0/parent = -1
bones/0/rest = Transform( 1, 0, 0, 0, 0, -1, 0, 1, 0, 0.038694, 0.252999, 0.0877164 )
bones/0/pose = Transform( 1.0, 0.0, -0.0, 0.0, 1.0, -0.0, -0.0, -0.0, 1.0, 0.0, 0.0, -0.0 )
bones/0/enabled = true
bones/0/bound_children = [ ]
bones/1/name = "Bone.002"
bones/1/parent = 0
bones/1/rest = Transform( 0.0349042, 0.99939, 0.000512929, -0.721447, 0.0248417, 0.692024, 0.691589, -0.0245245, 0.721874, 0, 5.96046e-08, -1.22688 )
bones/1/pose = Transform( 1.0, 0.0, -0.0, 0.0, 1.0, -0.0, -0.0, -0.0, 1.0, 0.0, 0.0, -0.0 )
bones/1/enabled = true
bones/1/bound_children = [ ]
BoneAttachment¶
BoneAttachment node is an intermediate node to describe some node being parented
to a single bone in a Skeleton node. The BoneAttachment has a
bone_name=NameOfBone
attribute, and the corresponding bone being the parent has the
BoneAttachment node in its bound_children
list.
Esimerkki yhdestä MeshInstance-solmusta, joka toimii Skeletonin luun isäntänä:
[node name="Armature" type="Skeleton" parent="."]
transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -0.0219986, 0.0125825, 0.0343127)
bones/0/name = "Bone"
bones/0/parent = -1
bones/0/rest = Transform(1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0)
bones/0/pose = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
bones/0/enabled = true
bones/0/bound_children = [NodePath("BoneAttachment:")]
[node name="BoneAttachment" type="BoneAttachment" parent="Armature"]
bone_name = "Bone"
[node name="Cylinder" type="MeshInstance" parent="Armature/BoneAttachment"]
mesh = SubResource(1)
transform = Transform(1.0, 0.0, 0.0, 0.0, 1.86265e-09, 1.0, 0.0, -1.0, 0.0, 0.0219986, -0.0343127, 2.25595)
Animaatiotoistin (AnimationPlayer)¶
AnimationPlayer works as an animation library. It stores animations listed in
the format anim/Name=SubResource(ResourceId)
; each line refers to an
Animation resource. All the animation resources use the root node of
AnimationPlayer. The root node is stored as
root_node=NodePath(Path/To/Node)
.
[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
root_node = NodePath("..")
autoplay = ""
playback_process_mode = 1
playback_default_blend_time = 0.0
playback_speed = 1.0
anims/default = SubResource( 2 )
blend_times = [ ]
Resurssit¶
Resurssit ovat komponentteja, joista solmut muodostuvat. Esimerkiksi MeshInstance-solmulla on ArrayMesh-resurssi. ArrayMesh-resurssi voi olla joko TSCN-tiedoston sisäinen tai sen ulkopuolinen.
References to the resources are handled by id
numbers in the resource's
heading. External resources and internal resources are referred to with
ExtResource(id)
and SubResource(id)
, respectively. Because there
have different methods to refer to internal and external resources, you can have
the same ID for both an internal and external resource.
Esimerkiksi resurssiin [ext_resource id=3 type="PackedScene" path=....]
voidaan viitata näin: ExtResource(3)
.
Ulkoiset resurssit¶
Ulkoiset resurssit ovat linkkejä resursseihin, jotka eivät sisälly TSCN-tiedostoon itsessään. Ulkoinen resurssi koostuu polusta, tyypistä ja ID:stä.
Godot always generates absolute paths relative to the resource directory and
thus prefixed with res://
, but paths relative to the TSCN file's location
are also valid.
Joitakin esimerkkejä ulkoisista resursseista:
[ext_resource path="res://characters/player.dae" type="PackedScene" id=1]
[ext_resource path="metal.tres" type="Material" id=2]
Like TSCN files, a TRES file may contain single-line comments starting with a
semicolon (;
). However, comments will be discarded when saving the resource
using the Godot editor.
Sisäiset resurssit¶
A TSCN file can contain meshes, materials and other data. These are contained in
the internal resources section of the file. The heading for an internal
resource looks similar to those of external resources, except that it doesn't
have a path. Internal resources also have key=value
pairs under each
heading. For example, a capsule collision shape looks like:
[sub_resource type="CapsuleShape" id=2]
radius = 0.5
height = 3.0
Some internal resources contain links to other internal resources (such as a mesh having a material). In this case, the referring resource must appear before the reference to it. This means that order matters in the file's internal resources section.
Unfortunately, documentation on the formats for these subresources isn't complete. Some examples can be found by inspecting saved resource files, but others can only be found by looking through Godot's source.
ArrayMesh¶
ArrayMesh koostuu useista pinnoista, jotka kukin ovat muotoa surface\Index={}
. Kullakin pinnalla on joukko kärkipisteitä ja materiaali.
TSCN-tiedostot tukevat kahta erilaista pinnan formaattia:
Vanhassa formaatissa kullakin pinnalla on kolme olennaista avainta:
primitive
arrays
morph_arrays
primitive
on enumeroitu muuttuja;primitive=4
joka on PRIMITIVE_TRIANGLES on usein käytetty.arrays
on kaksiulotteinen taulukko, joka sisältää:Taulukko kärkipisteiden sijainteja
Normals array
Taulukko tangentteja
Taulukko kärkipisteiden värejä
UV-taulukko 1
UV-taulukko 2
Taulukko luuindeksejä
Taulukko luiden painoja
Taulukko kärkipisteiden indeksejä
morph_arrays
on taulukko morpheja. Kukin morph on tarkalleenarrays
ilman kärkipisteiden indeksitaulukkoa.
Esimerkki ArrayMeshistä:
[sub_resource id=1 type="ArrayMesh"]
surfaces/0 = {
"primitive":4,
"arrays":[
Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, 1.0, -0.5),
Vector3Array(0.0, 0.609973, -0.792383, 0.686239, -0.609973, -0.396191, 0.0, -0.609973, -0.792383, 0.686239, 0.609973, -0.396191, 0.686239, -0.609973, 0.396191, 0.686239, 0.609973, 0.396191, 0.0, -0.609973, 0.792383, 0.0, 0.609973, 0.792383, -0.686239, -0.609973, 0.396191, -0.686239, 0.609973, 0.396191, -0.686239, -0.609973, -0.396191, -0.686239, 0.609973, -0.396191),
null, ; No Tangents,
null, ; no Vertex Colors,
null, ; No UV1,
null, ; No UV2,
null, ; No Bones,
null, ; No Weights,
IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 0, 5, 9, 9, 8, 10, 11, 10, 2, 1, 10, 8, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 5, 0, 3, 0, 9, 11, 9, 5, 7, 9, 10, 11, 11, 2, 0, 10, 1, 2, 1, 6, 4, 6, 1, 8)
],
"morph_arrays":[]
}
Animaatio¶
Animaatioresurssi koostuu raidoista. Lisäksi kullakin raidalla on pituus (length
), kierto (loop
) ja askellus (step
).
Sekä
length
ettästep
ilmaisevat aikaa sekunteina.
Kukin raita on kuvattu listana avain-arvo pareja tracks/Id/Attribute
. Kukin raita sisältää:
type
(tyyppi)path
(polku)interp
(interpolaatio)keys
(avainruudut)loop_wrap
(kierron tyyppi)imported
(tuotu)enabled
Kunkin raidan ensimmäisen attribuutin on oltava
type
.type
arvo voi olla:transform
(muunnos)value
(arvo)method
(metodi)
path
muoto onNodePath(Path/To/Node:Attribute)
. Se on polku AnimationPlayer solmussa määritellystä juurisolmusta animoituun solmuun tai attribuuttiin.The
interp
is the method to interpolate frames from the keyframes. It is an enum variable with one of the following values:0
(constant)1
(linear)2
(cubic)
The
keys
correspond to the keyframes. It appears as aPoolRealArray()
, but may have a different structure for tracks with different types.A Transform track uses every 12 real numbers in the
keys
to describe a keyframe. The first number is the timestamp. The second number is the transition followed by a 3-number translation vector, followed by a 4-number rotation quaternion (X, Y, Z, W) and finally a 3-number scale vector. The default transition in a Transform track is 1.0.
[sub_resource type="Animation" id=2]
length = 4.95833
loop = false
step = 0.1
tracks/0/type = "transform"
tracks/0/path = NodePath("Armature001")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = true
tracks/0/enabled = true
tracks/0/keys = PoolRealArray( 0, 1, -0.0358698, -0.829927, 0.444204, 0, 0, 0, 1, 0.815074, 0.815074, 0.815074, 4.95833, 1, -0.0358698, -0.829927, 0.444204, 0, 0, 0, 1, 0.815074, 0.815074, 0.815074 )
tracks/1/type = "transform"
tracks/1/path = NodePath("Armature001/Skeleton:Bone.001")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/imported = true
tracks/1/enabled = false
tracks/1/keys = PoolRealArray( 0, 1, 0, 5.96046e-08, 0, 0, 0, 0, 1, 1, 1, 1, 4.95833, 1, 0, 5.96046e-08, 0, 0, 0, 0, 1, 1, 1, 1 )