应使用 godot 官方 api(如 resourceloader::load)解析 .tscn 文件,因其为 godot 自研文本场景格式,含缩进层级、类型标注及资源引用等特有语义,通用解析器易出错;脱离运行时需手写解析器时,须严格处理缩进、bom 和基础类型。

Godot .tscn 文件不是标准 INI 或 YAML,别用通用解析器硬套
直接拿 inih、yaml-cpp 或正则暴力拆解 .tscn 文件,大概率会挂——因为它的语法是 Godot 自研的轻量文本场景格式(Text Scene),有特定语义:节点层级靠缩进 + [node] 块界定,属性赋值支持类型标注(如 position = Vector2(10, 20)),还允许内联数组、字典甚至嵌套资源引用。用通用格式工具读,会漏掉类型信息、误判缩进层级、无法还原 Resource 实例。
最稳路径:走 Godot 官方 C++ API,用 PackedScene::pack() 和 PackedScene::instantiate() 的逆向流程
Godot 4.x 的 C++ 暴露了完整的场景序列化/反序列化逻辑,但关键点在于:.tscn 是 PackedScene 的文本表示,而 PackedScene 本身可被 C++ 层直接加载并转为内存中的 Variant 树。你不需要手写解析器,而是复用引擎内部的 ResourceFormatLoaderText:
- 确保你的 C++ 项目链接了
godot-cpp并正确初始化了 Godot API(godot::GDExtensionBinding::init()) - 调用
godot::ResourceLoader::get_singleton()->load("res://xxx.tscn", "", godot::ResourceFormatLoader::CacheMode::CACHE_MODE_REUSE),返回Ref<packedscene></packedscene> - 对
PackedScene调用get_state()→ 得到Ref<packedscenestate></packedscenestate>,再遍历其get_node_count()、get_node_type(i)、get_node_property(i, "position")等方法提取结构 - 注意:该流程依赖 Godot 运行时环境(不能脱离
godot-cpp单独运行),且.tscn必须位于res://路径下(或通过ResourceLoader::add_path_remap()映射)
如果必须脱离 Godot 运行时(比如命令行工具),只能手写有限解析器,但得守住三条底线
纯 C++ 独立解析 .tscn 是可行的,但只建议用于只读、结构简单、无脚本/信号/资源嵌套的场景。核心约束如下:
-
缩进必须用空格,且每级严格 4 空格 —— Godot 导出默认如此,但用户可能改,遇到
\t或 2/8 空格就需预处理归一化 -
只解析基础类型和扁平属性:接受
int、float、String、Vector2、Color字面量(如Color(1, 0.5, 0, 1)),跳过SubResource、ExtResource、Script等需要资源系统解析的内容 -
节点名/路径必须按块顺序推导:
[node name="Node2" type="Control"]后紧跟的缩进属性属于该节点;下一个同级[node]出现前,所有缩进块都算子节点 —— 不能靠行号,得靠空格数比对
示例片段解析逻辑:
... [node name="Button" type="Button" parent="."] margin_left = 16.0 text = "Click me"
→ 检测到 margin_left 行缩进 0,说明它不属于任何子节点,而是当前 [node] 的直系属性;若缩进为 4,则归属上一个节点的子节点。
别忽略 .tscn 的编码与 BOM 问题
Godot 默认以 UTF-8 无 BOM 写入 .tscn,但 Windows 上某些编辑器(如旧版 Notepad)保存时会加 BOM。C++ 用 std::ifstream 读取时,若未跳过 BOM,会导致首行解析失败(如把 [node...] 读成 [node...])。解决方案:
- 读文件前先检查前 3 字节是否为
0xEF 0xBB 0xBF,是则跳过 - 或统一用
std::wifstream+std::locale绑定 UTF-8 facet(需 C++11 以上) - 更简单:用
godot::FileAccess::open()代替原生流,它自动处理 BOM 和换行符
实际工程中,BOM 和混合换行符(\r\n vs \n)导致的解析偏移,比语法错误更常引发静默失败。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











