TSCN文件格式

TSCN(文本场景)文件格式表示Godot中的单个场景树。TSCN文件的优点是大部分是人可读的,便于版本控制系统管理。导入过程中,TSCN文件被编译为二进制文件。 .scn 存储在.import文件夹中的文件。这样可以减小数据大小并加快加载速度。

escn(导出场景)文件格式与tscn文件格式相同,但用于向godot指示该文件已从其他程序导出,用户不应在godot中编辑。

对于那些寻找完整描述的人,解析是在文件中处理的。 resource_format_text.cppResourceFormatLoaderText 班级。

文件结构

TSCN文件中有五个主要部分:

  1. 文件描述符

  2. 外部资源

  3. 内部资源

  4. 结点

  5. 连接

文件描述符看起来像 [gd_scene load_steps=1 format=2] 应该是文件中的第一个条目。这个 load_steps 参数(理论上)应该是文件中的资源数量。然而,在实践中,它的价值似乎并不重要。

这些部分应该按顺序出现,但很难区分。它们之间唯一的区别是在该部分中所有项目的标题中的第一个元素。例如,所有外部资源的标题应以 [ext_resource .....] .

TSCN文件可以包含以分号开头的单行注释。 (; )但是,在使用godot编辑器保存文件时,注释将被丢弃。

文件中的条目

标题看起来像 [<resource_type> key=value key=value key=value ...] 其中资源类型为:

  • ext_resource

  • sub_resource

  • node

  • connection

每一个标题下面都是零或更多 key = value 对。值可以是复杂的数据类型,如数组、转换、颜色等。例如,空间节点如下所示:

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

场景树

场景树由…节点组成!每个节点的标题由其名称、父节点和(大多数情况下)类型组成。例如 [node type="Camera" name="PlayerCamera" parent="Player/Head"]

其他有效关键字包括:

  • instance

  • instance_placeholder

  • owner

  • index (如果两个节点同名)

  • groups

文件中的第一个节点(也是场景根)不能具有 parent=Path/To/Node 标题中的条目。所有场景文件都应该 one 场景根。否则,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

NodePath

树结构不足以代表整个场景。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:")
...

骨架

骨架节点继承空间节点,但也可能具有以密钥值对形式描述的骨骼列表。 bones/Id/Attribute=Value . 骨骼属性包括:

  • name

  • parent

  • rest

  • pose

  • enabled

  • bound_children

  1. name 必须是每个骨骼的第一个属性。

  2. parent 是骨骼列表中父骨骼的索引,使用父索引,骨骼列表将构建到骨骼树。

  3. rest 是骨骼在其“静止”位置的变换矩阵。

  4. pose 是姿势矩阵;使用 rest 作为基础。

  5. bound_children 是一个列表 NodePath() 指的是属于这根骨头的骨附着物。

下面是一个包含两个骨骼的骨骼节点示例:

[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

骨附着节点是一个中间节点,用来描述某个节点与骨骼节点中的单个骨骼的父节点。骨附着体有一个 bone_name=NameOfBone 属性,并且作为父对象的相应骨骼在其 bound_children 名单。

骨骼中骨骼的父级网格实例示例:

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

AnimationPlayer

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

资源

资源是构成节点的组件。例如,一个meshistance节点将有一个伴随的arraymesh资源。arraymesh资源可以是TSCN文件的内部或外部资源。

对资源的引用由 id 资源标题中的数字。外部资源和内部资源是指 ExtResource(id)SubResource(id) ,分别。由于引用内部和外部资源的方法不同,因此可以对内部和外部资源使用相同的ID。

例如,引用资源 [ext_resource id=3 type="PackedScene" path=....] ,您将使用 ExtResource(3) .

外部资源

外部资源是指向不包含在TSCN文件中的资源的链接。外部资源由路径、类型和ID组成。

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文件可以包含网格、材质和其他数据。这些都包含在 内部资源 文件的节。内部资源的标题与外部资源的标题类似,只是它没有路径。内部资源也有 key=value 在每个标题下配对。例如,胶囊碰撞形状如下:

[sub_resource  type="CapsuleShape" id=2]

radius = 0.5
height = 3.0

一些内部资源包含到其他内部资源(例如具有材质的网格)的链接。在这种情况下,引用的资源必须出现 之前 对它的引用。这意味着在文件的内部资源部分,顺序很重要。

不幸的是,这些子资源的格式文档并不完整。通过检查保存的资源文件可以找到一些示例,但其他示例只能通过查看Godot的源代码来找到。

ArrayMesh

阵列网格由多个曲面组成,每个曲面的格式都是 surface\Index={{}} . 每个曲面都是一组顶点和一个材质。

TSCN文件支持两种表面格式:

  1. 对于旧格式,每个面都有三个基本键:

  • primitive

  • arrays

  • morph_arrays

    1. primitive 是一个枚举变量, primitive=4 哪个是 PRIMITIVE_TRIANGLES 经常使用。

    2. arrays 是二维数组,它包含:

      1. 顶点位置数组

      2. 切线数组

      3. 顶点颜色数组

      4. 紫外线阵列1

      5. 紫外线阵列2

      6. 骨骼索引数组

      7. 骨骼权重数组

      8. 顶点索引数组

    3. morph_arrays 是一个变形数组。每个变形都是 arrays 没有顶点索引数组。

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

动画

动画资源由轨迹组成。另外,它有 lengthloopstep 应用于所有曲目。

  1. lengthstep 都是以秒为单位的持续时间。

每首曲目都由一个键值对列表描述,格式为 tracks/Id/Attribute . 每条轨道包括:

  • type

  • path

  • interp

  • keys

  • loop_wrap

  • imported

  • enabled

  1. 这个 type 必须是每个曲目的第一个属性。价值 type 可以是:

    • transform

    • value

    • method

  2. 这个 path 有格式 NodePath(Path/To/Node:attribute) . 它是动画节点或属性的路径,相对于动画播放器中定义的根节点。

  3. 这个 interp 是从关键帧插入帧的方法。它是一个枚举变量,可以具有值:

    • 0(常量)

    • 1(线性)

    • 2(立方)

  4. 这个 keys 对应于关键帧。它看起来像 PoolRealArray() ,但对于不同类型的轨道可能具有不同的结构。

    • 转换轨每12个实数使用 keys 描述关键帧。第一个数字是时间戳。第二个数字是转换,然后是3个数字的转换矢量,然后是4个数字的旋转四元数(x,y,z,w),最后是3个数字的比例矢量。变换轨迹中的默认变换为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 )