Godot系统架构
默认值
每个控件类型有类的默认值(硬编码,如 PRESET_TOP_LEFT,size = Vector2(0, 0))
编辑器在创建节点时会"智能"覆盖这个默认值:
- 根节点 → 覆盖为 PRESET_FULL_RECT(确保可见)
- 子节点 → 可能覆盖为其他值(取决于父节点类型)
文件引用
实例化同步
Godot 实例化同步规则如下:
| 更改类型 | 实例是否自动更新 |
|---|---|
| .tscn 里的属性值 | 会(继承) |
| .tscn 里连接的信号 | 会 |
| .tscn 根节点的 script | 会 |
| .tscn 里子节点的 script | 不会,需要重新实例化 |
属性链接
链接的本质是"差异存储"
Godot 实例并不存储完整属性,只存储与源场景的差异:
实例化文件(.tscn) 结构:
[ext_resource path="res://源场景.tscn" type="PackedScene"]
[node name="Player" ...] ← 只有"差异化"的属性才被存储属性状态的三种状态
| 状态 | 含义 | 存储位置 |
|---|---|---|
| 链接 | 值 = 源场景的值,无覆盖 | 不存储 |
| 覆盖 | 值 ≠ 源场景的值 | 存储在 .tscn |
| 被移除 | 显式重置为默认值 | 存储为 [] 或删除 |
四种现象的解释
| 现象 | 原因 |
|---|---|
| ① 场景变 → 实例跟着变 | 实例只存差异,基准值来自源场景 |
| ② 实例变 → 实例断开链接 | 检测到差异,创建覆盖,存储在 .tscn |
| ③ 实例值 == 场景值 → 恢复链接 | 差异消失,覆盖被移除,不再占用存储 |
| ④ 是否持续监控? | 不是实时监控,而是在序列化/反序列化时比较 |
关键机制
- 加载时:读取源场景 + 叠加实例覆盖
- 保存时:比较当前值与源值,只有不同时才写入
定位系统
Control的位置
Control 的位置由两部分决定
每个 Control 节点有:
- 锚点(Anchor) - 参照点,在父节点的哪个位置
- 偏移(Offset) - 相对于锚点偏移多少
锚点(Anchor)
想象父节点是一张纸,锚点是纸上的一个点:
| 锚点位置 | 效果 |
|---|---|
| 左上 | 参照父节点左上角 |
| 中心 | 参照父节点正中间 |
| 右下 | 参照父节点右下角 |
偏移(Offset)
偏移就是在锚点的基础上"挪多远":
- offset_left = 从锚点向左挪多少
- offset_right = 从锚点向右挪多少(决定宽度)
- offset_top = 从锚点向上挪多少
- offset_bottom = 从锚点向下挪多少(决定高度)
计算公式
子节点左边界 X = 父宽 × anchor_left + offset_left
子节点右边界 X = 父宽 × anchor_right + offset_right
子节点上边界 Y = 父高 × anchor_top + offset_top
子节点下边界 Y = 父高 × anchor_bottom+ offset_bottom
子节点尺寸 rect_size:
width = 右边界X − 左边界X
height = 下边界Y − 上边界Y碰撞系统
Collision Layer 与 Collision Mask
将这两个属性结合起来理解:
- Collision Layer: 我属于哪个阵营
- Collision Mask: 我能检测到哪些阵营
角色举例
| 对象 | Layer(我是谁) | Mask(我能检测谁) |
|---|---|---|
| 玩家 | 第1层 | 第2层(敌人)、第3层(障碍物) |
| 敌人 | 第2层 | 第1层(玩家) |
| 地面 | 第3层 | 第1层(玩家)、第2层(敌人) |
实际效果
当玩家发射火球时:
- 火球:
- Layer: 第1层(和玩家同阵营)
- Mask: 第2层(只检测敌人)
- 碰到敌人 → 触发碰撞回调
Collision Mask = 0 的含义
- 不检测任何层 → 穿过所有东西 → 相当于没有碰撞检测
简单记忆
- Layer = "我是谁"
- Mask = "谁能进入我的范围"
注释系统
csv 方式
Godot 4 导入 CSV 翻译文件的关键在于理解它的导入机制:你只需要操作 .csv 源文件,Godot 会在后台自动生成并管理 .translation 文件及其 .import 配置文件。
✍️ CSV 文件编写与格式规范
一个合法的 CSV 文件需要遵循固定的格式。
- 基本结构: 文件的第一列必须是
keys(或任意命名,但内容必须为键名),随后每一列代表一种语言,用语言代码(如en,zh_CN,ja)作为列标题。 - 第一行: 必须包含
keys和所有语言代码。左上角的单元格(第一行第一列)内容会被忽略,可以留空。 - 后续行: 每一行定义一个文本键及其在各种语言下的翻译文本。
- 键命名: 键值需要
KEY标签必须唯一且通常建议全大写(如GREET)以区分普通文本。大小写敏感,KEY1和Key1会被视为不同的键。 - 语言代码: 必须使用引擎支持的有效语言环境代码,且需使用下划线连接(如
zh_CN正确,zh-CN错误)。 - 特殊注释列: 如果想添加不会被导入的注释列,可以让其列标题以下划线
_开头(如_Note)。
一个标准的示例如下:
| keys | en | zh_CN | ja |
|---|---|---|---|
| GREET | Hello, friend! | 你好,朋友! | こんにちは |
| ASK | How are you? | 你好吗? | お元気ですか |
| BYE | Goodbye | 再见 | さようなら |
| QUOTE | "Hello" said the man. | “你好”男人说。 | 「こんにちは」男は言いました |
对应的纯文本 CSV 内容如下:
keys,en,zh_CN,ja
GREET,"Hello, friend!","你好,朋友!","こんにちは"
ASK,How are you?,你好吗?,お元気ですか
BYE,Goodbye,再见,さようなら
QUOTE,"""Hello"" said the man.","“你好”男人说。","「こんにちは」男は言いました"特别注意:
- 编码: 文件必须以 UTF-8 编码保存,且不能包含 BOM(字节顺序标记)。
- 文本中的特殊字符:
- 如果文本中包含逗号、换行符或双引号,则整个文本必须用一对双引号括起来。
- 文本内的双引号本身,则需要用两个连续的双引号来转义(如
""Hello"" said the man.)。
- 编辑工具: 推荐使用 VS Code、Sublime Text、Notepad++ 或 LibreOffice Calc 等工具编辑,它们能更好地处理 UTF-8 编码。Microsoft Excel 默认可能会保存为 ANSI 编码,需额外注意。
⚙️ 自动导入与项目配置
自动生成
.translation文件 将编写好的.csv文件放入你的 Godot 项目目录(如res://translations/)后,编辑器会自动识别并导入。你会在.csv文件旁边看到自动生成的.translation文件和一个.import配置文件。- 导入设置:你可以选中
.csv文件,在 导入 面板中调整压缩(建议保持默认勾选以减小体积)和分隔符等选项,修改后记得点击 “重新导入” 。
- 导入设置:你可以选中
添加到项目设置 为了让游戏加载这些翻译,你需要手动将它们添加到项目配置。
- 路径:打开
工程 -> 项目设置 -> 本地化(Localization)标签页。 - 操作:点击
Translations列表旁的Add...按钮,选择那些由 CSV 生成的.translation文件添加到列表中。
- 路径:打开
🗑️ 关于删除翻译文件的正确方式
Godot 4 的自动导入机制要求:.translation 文件是基于 CSV 文件自动生成的,不应该被手动删除。因为 Godot 在每次打开项目时都会重新检查 .csv 文件的导入设置,如果发现 .translation 文件缺失,会自动重新生成。同时,你也要注意同步管理 .import 文件和项目设置。
- 如果你不再需要某个翻译,完整的移除步骤如下:
- 在编辑器中移除引用:打开
项目设置 -> 本地化,在Translations列表中选中对应的.translation条目,点击Delete删除。 - 在文件系统中删除源文件:在你的操作系统中,直接删除对应的
.csv源文件。 - 清理生成的文件:删除相关文件后,Godot 不会再自动生成它们。但你可能偶尔会看到残留的
.translation.import文件。这时,你可以在操作系统中找到并手动删除它们,或者使用工程 -> 工具 -> 孤儿资源清理器...工具来扫描并清理这些无用的文件。
- 在编辑器中移除引用:打开
🔧 常见问题与注意事项
- 文本显示异常:确保 CSV 为 UTF-8 无 BOM 编码;检查代码中是否正确调用
tr()函数并返回了翻译文本;语言代码是否有效;以及场景中 GUI 控件是否已正确配置字体以支持目标语言字符。 - CSV 与 PO 文件的选择:CSV 直观易上手,适合大多数场景。但其无法处理复数规则(如代码中的
1 apple和2 apples)等功能。若项目需要,需转向gettext的 PO 文件方案。 - 自动导入:自动生成由导入系统自动完成,不需要手动配置。但记得将生成的
.translation文件添加到项目设置的翻译列表中。 - 运行时动态加载:Godot 的
TranslationServer支持在游戏运行时动态添加或移除翻译文件。但.translation文件本身必须是存在的,删除操作通常指在项目设置中移除引用,而非删除生成的二进制文件。
Godot 4 的导入逻辑相对宽容:
它只统计逗号的数量来判断表格列数。
它默认假定第一列用于存放翻译键。
它不会校验第一列的标题文本内容是什么。
所以理论上怎么写都对:
# keys,en,zh_CN
keys,en,zh_CN
key,en,zh_CN
ATTR_MP,MP,魔法值建议使用 keys,en,zh_CN, 只要格式正确,godot会自动识别并编译对应语言的 .translation 文件