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 de arquivo TSCN
O formato de arquivo TSCN (cena de texto) representa uma única árvore de cena dentro do Godot. Ao contrário dos arquivos SCN binários, os arquivos TSCN têm a vantagem de serem legíveis por humanos e fáceis de gerenciar por sistemas de controle de versão.
O formato de arquivo ESCN (cena exportada) é idêntico ao formato de arquivo TSCN, mas é usado para indicar ao Godot que o arquivo foi exportado de outro programa e não deve ser editado pelo usuário dentro do Godot. Ao contrário dos arquivos SCN e TSCN, durante a importação, os arquivos ESCN são compilados para arquivos SCN binários armazenados dentro da pasta .godot/imported/. Isso reduz o tamanho dos dados e acelera o carregamento, já que formatos binários são mais rápidos de carregar em comparação com formatos baseados em texto.
Para tornar os arquivos mais compactos, propriedades iguais ao valor padrão não são armazenadas nos arquivos de cena/recurso. É possível escrevê-las manualmente, mas elas serão descartadas ao salvar o arquivo.
Para aqueles que procuram uma descrição completa, o parsing é tratado no arquivo resource_format_text.cpp na classe ResourceFormatLoaderText.
Nota
Os formatos de arquivo de cena e recurso mudaram significativamente no Godot 4, com a introdução de UIDs baseados em strings para substituir os IDs inteiros incrementais.
Os dados de malha (mesh), esqueleto e animação também são armazenados de forma diferente em comparação com o Godot 3. Você pode ler sobre algumas das mudanças neste artigo: Reformulação de dados de animação para o 4.0
Cenas e recursos salvos com o Godot 4.x contêm format=3 em seus cabeçalhos, enquanto o Godot 3.x usa format=2.
Estrutura do arquivo
Existem cinco seções principais dentro do arquivo TSCN:
Descritor de arquivo
Recursos externos
Recursos internos
Nós
Conexões
O descritor de arquivo se parece com [gd_scene format=3 uid=\"uid://cecaux1sm7mo0\"] e deve ser a primeira entrada no arquivo. Note que cenas salvas antes do Godot 4.6 também terão um atributo load_steps=<int> no descritor de arquivo. Esse atributo agora está obsoleto e deve ser ignorado caso esteja presente.
O uid é um identificador exclusivo baseado em string que representa a cena. Ele é usado pela engine para rastrear arquivos que são movidos de lugar, mesmo enquanto o editor está fechado. Os scripts também podem carregar recursos baseados em UID usando o prefixo de caminho uid:// para evitar a dependência de caminhos do sistema de arquivos. Isso torna possível mover um arquivo no projeto e ainda assim conseguir carregá-lo em scripts sem ter que modificar o script. O Godot não usa arquivos externos para rastrear os IDs, o que significa que nenhum local central de armazenamento de metadados é necessário dentro do projeto. Veja este pull request para informações detalhadas.
Essas seções devem aparecer em ordem, mas pode ser difícil distingui-las. A única diferença entre elas é o primeiro elemento no cabeçalho para todos os itens na seção. Por exemplo, o cabeçalho de todos os recursos externos deve começar com [ext_resource ...].
Um arquivo TSCN pode conter comentários de linha única começando com um ponto e vírgula (;). No entanto, os comentários serão descartados ao salvar o arquivo usando o editor Godot. Espaços em branco dentro de um arquivo TSCN não são significativos (exceto dentro de strings), mas espaços em branco extras serão descartados ao salvar o arquivo.
Entradas dentro do arquivo
Um título se parece com [<resource_type> key1=value1 key2=value2 key3=value3 ...] onde resource_type é um dos seguintes:
ext_resourcesub_resourcenodeconnection
Abaixo de cada cabeçalho vêm zero ou mais pares chave = valor. Os valores podem ser tipos de dados complexos, como Arrays, Transforms, Colors, e assim por diante. Por exemplo, um Node3D parece:
[node name="Cube" type="Node3D" unique_id=224283918]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 2, 3)
A árvore da cena
A árvore de cena é composta de… nós! O cabeçalho de cada nó consiste em seu nome, pai, um ID único (usado para rastrear nós mesmo que sejam movidos ou renomeados) e, na maioria das vezes, um tipo. Por exemplo: [node name="PlayerCamera" type="Camera" parent="Player/Head" unique_id=1697057368]
Note que o unique_id está presente apenas em cenas salvas com o Godot 4.6 ou posterior. Portanto, não há garantia de que ele estará presente.
Outras palavras-chave válidas incluem:
instance
instance_placeholder
owner
index(define a ordem de aparecimento na árvore; se ausente, nós herdados terão precedência sobre os simples)
groups
node_paths(lista nomes de propriedades exportadas como um tipo Node, mas referenciadas como um NodePath no arquivo)
O primeiro nó no arquivo, que também é a raiz da cena, não deve ter uma entrada parent="Path/To/Node" em seu cabeçalho. Todos os arquivos de cena devem ter exatamente uma raiz de cena. Se não tiver, o Godot falhará ao importar o arquivo. O caminho pai de outros nós deve ser absoluto, mas não deve conter o nome da raiz da cena. Se o nó for um filho direto da raiz da cena, o caminho deve ser ".". Aqui está uma árvore de cena de exemplo (mas sem qualquer conteúdo de nó):
[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"
Dica
Para tornar a estrutura do arquivo mais fácil de compreender, você pode salvar um arquivo com qualquer nó ou recurso específico e depois inspecioná-lo você mesmo em um editor externo. Você também pode fazer alterações incrementais no editor do Godot e manter um editor de texto externo aberto no arquivo .tscn ou .tres com o recarregamento automático ativado para ver o que muda.
Aqui está um exemplo de uma cena contendo uma bola baseada em RigidBody3D com colisão, visuais (mesh + luz) e uma câmera vinculada como filha ao 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 (Caminho de Nó)
Uma estrutura de árvore não é suficiente para representar a cena inteira. O Godot usa uma estrutura NodePath(Path/To/Node) para referir-se a outro nó ou atributo do nó em qualquer lugar na árvore de cena. Caminhos são relativos ao nó atual, com NodePath(".") apontando para o nó atual e NodePath("") apontando para nenhum nó.
Por exemplo, MeshInstance3D usa NodePath() para apontar para seu esqueleto. Da mesma forma, faixas de animação usam NodePath() para apontar para propriedades de nó a serem animadas.
O NodePath também pode apontar para uma propriedade usando um sufixo :nome_da_propriedade, e até mesmo apontar para um componente específico para tipos de vetor, transform e cor. Isso é usado por recursos de Animação para apontar para propriedades específicas a serem animadas. Por exemplo, NodePath(\"MeshInstance3D:scale.x\") aponta para o componente x da propriedade Vector3 scale no MeshInstance3D.
Por exemplo, a propriedade skeleton no nó MeshInstance3D chamado mesh aponta para seu pai, Armature01:
[node name="mesh" type="MeshInstance3D" parent="Armature01" unique_id=1638249225]
skeleton = NodePath("..")
Skeleton3D
O nó Skeleton3D herda o nó Node3D, mas também pode ter uma lista de ossos descritos em pares chave-valor no formato bones/<id>/<attribute> = value. Os atributos de osso consistem em:
position: Vector3rotation: Quaternionscale: Vector3
Esses atributos são todos opcionais. Por exemplo, um osso pode definir apenas position ou rotation sem definir as outras propriedades.
Eis um exemplo de um nó esqueleto com dois ossos:
[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
O nó BoneAttachment3D é um nó intermediário para descrever algum nó sendo pai de um único osso em um nó Skeleton. O BoneAttachment tem uma propriedade bone_name = "name of bone", bem como uma propriedade para o índice do osso correspondente.
Um exemplo de um nó Marker3D pai de um osso em 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 (Reprodutor de Animação)
O nó AnimationPlayer funciona com uma ou mais bibliotecas de animação armazenadas em recursos AnimationLibrary. Uma biblioteca de animação é uma coleção de recursos individuais Animation, cuja estrutura está documentada aqui.
Essa divisão entre as animações em si e as bibliotecas de animação foi feita no Godot 4, para que as animações possam ser importadas separadamente das malhas 3D, o que é um fluxo de trabalho comum em softwares de animação 3D. Veja o pull request original para detalhes.
Se o nome da biblioteca estiver vazio, ela agirá como a fonte exclusiva de animações para este AnimationPlayer. Isso permite usar <nome_da_animação> diretamente para reproduzir animações por script. Se você der um nome à biblioteca, deverá reproduzi-la como <nome_da_biblioteca>/<nome_da_animação>. Isso garante a compatibilidade com versões anteriores e mantém o fluxo de trabalho existente se você não quiser usar múltiplas bibliotecas de animação.
Recursos
Recursos são componentes que compõem os nós. Por exemplo, um nó MeshInstance3D terá um recurso ArrayMesh acompanhante. O recurso ArrayMesh pode ser interno ou externo ao arquivo TSCN.
As referências aos recursos são gerenciadas por IDs exclusivos baseados em strings no cabeçalho do recurso. Isso é diferente da propriedade uid, que cada recurso externo também possui (mas subrecursos não).
Recursos externos e recursos internos são referidos com ExtResource("id") e SubResource("id"), respectivamente. Como existem métodos diferentes para referir-se a recursos internos e externos, você pode ter o mesmo ID tanto para um recurso interno quanto para um externo.
Por exemplo, para referir-se ao recurso [ext_resource type="Material" uid="uid://c4cp0al3ljsjv" path="res://material.tres" id="1_7bt6s"], você usaria ExtResource("1_7bt6s").
Recursos externos
Recursos externos são links para recursos não contidos no próprio arquivo TSCN. Um recurso externo consiste em um caminho, um tipo, um UID (usado para mapear sua localização no sistema de arquivos para um identificador único) e um ID (usado para referir-se ao recurso no arquivo de cena).
Godot sempre gera caminhos absolutos relativos ao diretório de recursos e, portanto, prefixados com res://, mas caminhos relativos à localização do arquivo TSCN também são válidos.
Alguns exemplos de recursos externos são:
[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"]
Assim como os arquivos TSCN, um arquivo TRES pode conter comentários de linha única começando com um ponto e vírgula (;). No entanto, os comentários serão descartados ao salvar o recurso usando o editor Godot. Espaços em branco dentro de um arquivo TRES não são significativos (exceto dentro de strings), mas espaços em branco extras serão descartados ao salvar o arquivo.
Recursos internos
Um arquivo TSCN pode conter malhas, materiais e outros dados. Eles estão contidos na seção internal resources do arquivo. O título de um recurso interno é semelhante ao de recursos externos, exceto pelo fato de não ter um caminho. Os recursos internos também têm pares key = value em cada título. Por exemplo, uma forma de colisão de cápsula se parece com:
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_fdxgg"]
radius = 1.0
height = 3.0
Alguns recursos internos contêm links para outros recursos internos (como uma malha com um material). Nesse caso, o recurso de referência deve aparecer antes da referência a ele. Isso significa que a ordem é importante na seção de recursos internos do arquivo.
ArrayMesh
Um ArrayMesh consiste em várias superfícies contidas na array _surfaces (note o sublinhado inicial). Os dados de cada superfície são armazenados em um dicionário com as seguintes chaves:
aabb: A caixa delimitadora alinhada aos eixos (axis-aligned bounding box) computada para visibilidade.attribute_data: Dados de atributos de vértice, como normais, tangentes, cores de vértice, UV1, UV2 e dados de vértice personalizados.bone_aabbs: A caixa delimitadora alinhada aos eixos de cada osso para visibilidade.format: O formato de buffer da superfície.index_count: O número de índices na superfície. Deve corresponder ao tamanho deindex_data.index_data: Os dados de índice, que determinam quais vértices devertex_datasão desenhados.lods: Variações de nível de detalhe (LOD), armazenadas como uma array. Cada nível de LOD representa dois valores na array. O primeiro valor é a porcentagem de espaço na tela para a qual o nível de LOD é mais adequado (comprimento da aresta); o segundo valor é a lista de índices que devem ser desenhados para o nível de LOD fornecido.material: O material usado ao desenhar a superfície.name: O nome da superfície. Pode ser usado em scripts e é importado de softwares DCC 3D.primitive: O tipo primitivo da superfície, correspondendo ao enumMesh.PrimitiveTypedo Godot.0= pontos,1= linhas,2= linha contínua (line strip),3= triângulos (mais comum),4= malha de triângulos (triangle strip).skin_data: Dados de peso dos ossos (bone weight).vertex_count: Número de vértices na superfície. Deve corresponder ao tamanho devertex_data.vertex_data: Os dados de posição dos vértices.
Aqui está um exemplo de um ArrayMesh salvo em seu próprio arquivo .tres. Alguns campos foram encurtados com ... por brevidade:
[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
Animação
Cada animação tem as seguintes propriedades:
length: O comprimento da animação em segundos. Note que os keyframes podem ser colocados fora do intervalo[0; length], mas podem não ter efeito dependendo do modo de interpolação escolhido.loop_mode:0= sem repetição,1= repetição cíclica (wrap-around),2= repetição travada (clamped).step: O tamanho do passo a ser usado ao editar esta animação no editor. Isso é usado apenas no editor; não afeta a reprodução da animação de forma alguma.
Cada faixa é descrita por uma lista de pares chave-valor no formato tracks/<id>/<attribute>. Cada faixa inclui:
type: O tipo da faixa (track). Isso define que tipo de propriedades podem ser animadas por esta faixa e como ela será exposta ao usuário no editor. Os tipos válidos sãovalue(faixa de propriedade genérica),position_3d,rotation_3d,scale_3d,blend_shape(faixas de animação 3D otimizadas),method(faixas de chamada de método),bezier(faixas de curva Bezier),audio(faixas de reprodução de áudio),animation(faixas que reproduzem outras animações).imported:truese a faixa foi criada a partir de uma cena 3D importada,falsese foi criada manualmente pelo usuário no editor do Godot ou usando um script.enabled:truese a faixa está ativa,falsese foi desativada no editor.path: Caminho para a propriedade do nó que será afetada pela faixa. A propriedade é escrita após o caminho do nó com um separador:.interp: O modo de interpolação a ser usado.0= mais próximo (nearest),1= linear,2= cúbico,3= ângulo linear,4= ângulo cúbico.loop_wrap:truese a faixa foi projetada para fazer a transição cíclica (wrap around) quando a animação estiver em loop,falsese a faixa travar nos primeiros/últimos keyframes.keys: Os valores da faixa de animação. A estrutura deste atributo depende dotype.
Aqui está uma cena contendo um AnimationPlayer que reduz a escala de um cubo ao longo do tempo usando uma faixa de propriedade genérica. O fluxo de trabalho de AnimationLibrary não foi usado, então a biblioteca de animação tem um nome vazio (mas a animação ainda recebe o nome de scale_down). Note que a faixa RESET não foi criada neste AnimationPlayer por brevidade:
[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")
Para faixas de propriedade genérica do tipo value, keys é um dicionário contendo 3 arrays com posições em times (PackedFloat32Array), valores de atenuação em transitions (PackedFloat32Array) e valores em values (Array). Há uma propriedade adicional update, que é um número inteiro com os valores 0 = contínuo, 1 = discreto, 2 = captura.
Aqui está um segundo recurso de Animação que faz uso das faixas de Posição 3D e Rotação 3D. Essas faixas (além da faixa de Escala 3D) substituem as faixas de Transform do Godot 3. Elas são otimizadas para reprodução rápida e podem opcionalmente ser compactadas.
A desvantagem desses tipos de faixas otimizadas é que elas não podem usar valores de atenuação (easing) personalizados. Em vez disso, todos os keyframes usam interpolação linear. Dito isso, você ainda pode optar por usar a interpolação mais próxima ou cúbica para todos os keyframes em uma determinada faixa, alterando o modo de interpolação da faixa.
[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)
Para faixas de posição, rotação e escala 3D, keys é um PackedFloat32Array com todos os valores armazenados em sequência.
No guia visual abaixo, T é o tempo do keyframe em segundos desde o início da animação, E é a transição do keyframe (atualmente sempre 1). Para faixas de posição e escala 3D, X, Y, Z são as coordenadas do Vector3. Para faixas de rotação 3D, X, Y, Z e W são as coordenadas do Quaternion.
# 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, ...)