Формат файла TSCN¶
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.
Формат файла ESCN (экспортированная сцена) идентичен формату файла TSCN, но используется для указания Godot, что файл был экспортирован из другой программы и не должен редактироваться пользователем внутри Godot. В отличие от файлов SCN и TSCN, при импорте файлы ESCN компилируются в двоичные файлы SCN, хранящиеся в папке .import/. Это уменьшает размер данных и ускоряет загрузку, так как двоичные форматы загружаются быстрее, чем текстовые.
Для тех, кто ищет полное описание, парсинг выполняется в файле resource_format_text.cpp в классе ResourceFormatLoaderText.
Структура файла¶
TSCN-файл состоит из пяти основных секций:
Дескриптор файла
Внешние ресурсы
Внутренние ресурсы
Узлы
Соединения
Дескриптор файла имеет вид [gd_scene load_steps=3 format=2] и должен быть первой записью в файле. Параметр load_steps равен общему количеству ресурсов (внутренних и внешних) плюс один (для самого файла). Если файл не имеет ресурсов, то load_steps опускается. Движок все равно загрузит файл правильно, если load_steps неверно, но это повлияет на загрузочные полосы и любой другой код, полагающийся на это значение.
Эти разделы должны появляться по порядку, но их бывает трудно различить. Единственное различие между ними - это первый элемент в заголовке для всех элементов раздела. Например, заголовок всех внешних ресурсов должен начинаться с [ext_resource .....].
Файл TSCN может содержать однострочные комментарии, начинающиеся с точки с запятой (;). Однако комментарии будут отброшены при сохранении файла с помощью редактора Godot.
Записи внутри файла¶
Заголовок выглядит как [<resource_type> key=value key=value key=value ...], где тип_ресурса является одним из:
ext_resourcesub_resourcenodeconnection
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 )
Дерево сцены¶
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"]
Other valid keywords include:
instance
instance_placeholder
owner
index(задает порядок появления в дереве. Если отсутствует, наследуемые узлы будут иметь приоритет над простыми)
groups
Первый узел в файле, который также является корнем сцены, не должен иметь запись parent=Path/To/Node в своем заголовке. Все файлы сцен должны иметь ровно один корень сцены. Если этого не произойдет, Godot не сможет импортировать файл. Родительский путь других узлов должен быть абсолютным, но не должен содержать имя корня сцены. Если узел является прямым потомком корня сцены, путь должен быть ".". Вот пример дерева сцены (но без содержимого узла):
[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"]
Подобно внутреннему ресурсу, документ для каждого узла в настоящее время является неполным. К счастью, это легко выяснить, так как вы можете просто сохранить файл с этим узлом. Примерами узлов являются:
[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
NоdePath¶
Древовидной структуры недостаточно для представления всей сцены. Godot использует структуру NodePath(Path/To/Node) для ссылки на другой узел или атрибут узла в любом месте дерева сцены. Например, MeshInstance использует NodePath() для указания на свой скелет. Аналогично, треки анимации используют NodePath() для указания на свойства узла для анимации.
[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:")
...
Скелет¶
Узел Skeleton наследует узел Spatial, но также может иметь список костей, описанных в парах ключ-значение в формате bones/Id/Attribute=Value. Атрибуты костей состоят из:
имяparentrestposeenabledbound_children
namemust be the first attribute of each bone.parentis the index of parent bone in the bone list, with parent index, the bone list is built to a bone tree.restis the transform matrix of bone in its "resting" position.poseis the pose matrix; userestas the basis.bound_childrenis a list ofNodePath()which point to BoneAttachments belonging to this bone.
Here's an example of a skeleton node with two bones:
[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 является промежуточным узлом для описания некоторого узла, являющегося родительским для одной кости в узле Skeleton. Узел BoneAttachment имеет атрибут bone_name=NameOfBone, а соответствующая кость, являющаяся родителем, имеет узел BoneAttachment в списке bound_children.
Пример одного MeshInstance, родительского по отношению к кости в Skeleton:
[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)
АnimationPlayer¶
AnimationPlayer работает как библиотека анимаций. Он хранит анимации, перечисленные в формате anim/Name=SubResource(ResourceId); каждая строка ссылается на ресурс анимации. Все анимационные ресурсы используют корневой узел AnimationPlayer. Корневой узел хранится как 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 = [ ]
Ресурсы¶
Ресурсы - это компоненты, из которых состоят узлы. Например, узел MeshInstance будет иметь сопутствующий ресурс ArrayMesh. Ресурс ArrayMesh может быть как внутренним, так и внешним по отношению к файлу TSCN.
Ссылки на ресурсы обрабатываются номерами id в заголовке ресурса. Внешние и внутренние ресурсы обозначаются соответственно ExtResource(id) и SubResource(id). Поскольку существуют различные методы ссылки на внутренние и внешние ресурсы, вы можете иметь один и тот же ID для внутреннего и внешнего ресурса.
Например, чтобы обратиться к ресурсу [ext_resource id=3 type="PackedScene" path=....], вы будете использовать ExtResource(3).
Внешние ресурсы¶
Внешние ресурсы - это ссылки на ресурсы, не содержащиеся в самом файле TSCN. Внешний ресурс состоит из пути, типа и идентификатора.
Godot всегда генерирует абсолютные пути относительно каталога ресурсов и, следовательно, с префиксом res://, но пути относительно местоположения файла TSCN также допустимы.
Примерами внешних ресурсов являются:
[ext_resource path="res://characters/player.dae" type="PackedScene" id=1]
[ext_resource path="metal.tres" type="Material" id=2]
Как и файлы TSCN, файл TRES может содержать однострочные комментарии, начинающиеся с точки с запятой (;). Однако комментарии будут отброшены при сохранении ресурса с помощью редактора Godot.
Внутренние ресурсы¶
Файл TSCN может содержать сетки, материалы и другие данные. Они содержатся в разделе внутренние ресурсы файла. Заголовок внутреннего ресурса выглядит так же, как и заголовки внешних ресурсов, за исключением того, что у него нет пути. Внутренние ресурсы также имеют пары ``ключ=значение'' под каждым заголовком. Например, форма столкновения капсулы выглядит следующим образом:
[sub_resource type="CapsuleShape" id=2]
radius = 0.5
height = 3.0
Некоторые внутренние ресурсы содержат ссылки на другие внутренние ресурсы (например, сетка, имеющая материал). В этом случае ссылающийся ресурс должен появиться перед ссылкой на него. Это означает, что порядок имеет значение в разделе внутренних ресурсов файла.
К сожалению, документация по форматам этих подресурсов неполная. Некоторые примеры можно найти, изучив сохраненные файлы ресурсов, но другие можно найти, только просмотрев исходный текст Godot.
ArrayMеsh¶
ArrayMesh состоит из нескольких поверхностей, каждая из которых имеет формат ``surfaceIndex={}`. Каждая поверхность представляет собой набор вершин и материал.
Файлы TSCN поддерживают два формата поверхности:
В старом формате каждая поверхность имеет три основные клавиши:
primitivearraysmorph_arraysprimitive- это переменная перечисления, часто используетсяprimitive=4, которая являетсяPRIMITIVE_TRIANGLES.arrays- это двумерный массив, он содержит:Vertex positions array
Normals array
Массив касательных
Массив цветов вершин
UV массив 1
UV массив 2
Массив индексов костей
Массив весов костей
Массив вершинных индексов
morph_arraysis an array of morphs. Each morph is exactly anarrayswithout the vertex indexes array.
Пример ArrayMesh:
[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":[]
}
Анимация¶
Анимационный ресурс состоит из дорожек. Кроме того, у него есть длительность (length), петля (loop) и шаг (step), применяемые ко всем дорожкам.
длительностьишаг- это продолжительность в секундах.
Каждый трек описывается списком пар ключ-значение в формате tracks/Id/Attribute. Каждый трек включает в себя:
тип(type)pathinterpключи(keys)loop_wrapимпортировано(imported)enabled
Атрибут
typeдолжен быть первым атрибутом каждого трека. Значениеtypeможет быть:transformvalueметод(method)
pathимеет форматNodePath(Path/To/Node:attribute). Это путь к анимированному узлу или атрибуту, относительно корневого узла, определенного в AnimationPlayer.interp- это метод интерполяции кадров из ключевых кадров. Это переменная enum с одним из следующих значений:0(константа)1(linear)2(cubic)
The
keyscorrespond 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
keysto 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 )