Godot Dialogue Manager - VSCode 扩展
为 Godot 4.x Dialogue Manager 提供完整开发支持的 VSCode 扩展 📖 目录✨ 核心功能🎨 完整的语法高亮
🧠 智能代码补全
🔍 悬停提示
🚀 跳转到定义
🔧 实时诊断与快速修复
📦 文案导出
🗂️ 代码折叠
🚀 快速开始1. 安装扩展方法 A:从 VSCode 市场安装
方法 B:手动安装
|
| 类别 | 标签 | 说明 |
|---|---|---|
| 时间控制 | [wait], [speed], [pause] |
控制对话显示速度和等待时间 |
| 音效 | [sound], [voice] |
播放音效和语音 |
| 文本效果 | [wave], [shake], [rainbow], [ghost], [pulse] |
文字动画效果 |
| UI 控制 | [br], [signal], [next], [auto], [jump] |
换行、信号、自动播放等 |
| BBCode | [b], [i], [u], [s], [color], [font], [size] |
富文本格式 |
🔹 示例
NPC: 你好[wait=1.5],欢迎来到这里!
这是[wave]波浪文字[/wave]效果。
[sound path="res://audio/coin.wav"]你获得了金币!
🔹 智能占位符
插入标签时自动生成占位符:
[wait=|] # 光标停在 | 位置
[sound path="|"] # 光标停在路径位置
[wave]|[/wave] # 自动闭合,光标在中间
5️⃣ 自定义元数据标签
🔹 配置自定义标签
在 settings.json 中配置:
{
"dialogue.diagnostics.customTags": {
"happy": {
"description": "快乐表情",
"example": "NPC: 你好![#happy]",
"category": "face",
"alias": ["开心", "高兴"]
},
"knock_sound": {
"description": "敲门音效",
"example": "[#knock_sound]",
"category": "se",
"alias": ["敲门"]
}
},
"dialogue.diagnostics.metadataCategories": {
"face": {
"icon": "😊",
"description": "表情"
},
"se": {
"icon": "🔊",
"description": "音效"
}
}
}
🔹 使用
NPC: 你好![#happy] # 或 [#开心]
*敲门* [#knock_sound] # 或 [#敲门]
🔹 管理标签
右键菜单 → Dialogue: 打开标签配置 或 Dialogue: 添加新元数据标签
6️⃣ 全局变量支持
🔹 配置全局变量
在 settings.json 中定义:
{
"dialogue.diagnostics.globalVariables": {
// 简单类型
"playerName": {
"type": "String",
"comment": "玩家角色名"
},
"gold": {
"type": "int",
"comment": "当前金币数"
},
// 复杂嵌套类型
"playerStats": {
"type": "Dictionary",
"comment": "玩家属性",
"schema": {
"hp": {
"type": "int",
"comment": "血量"
},
"skills": {
"type": "Array",
"itemType": "String",
"comment": "技能列表"
},
"equipment": {
"type": "Dictionary",
"comment": "装备信息",
"schema": {
"weapon": { "type": "String" },
"armor": { "type": "String?", "comment": "可选" }
}
}
}
}
}
}
🔹 使用
# ✅ 访问全局变量
if gold >= 100
NPC: 你的金币:{{gold}}
endif
# ✅ 访问嵌套属性
set playerStats.hp += 10
if playerStats.equipment.weapon == "sword"
NPC: 你装备了剑!
endif
# ✅ 数组操作
if "fireball" in playerStats.skills
NPC: 你会火球术!
endif
🔹 类型检查
扩展会验证:
- 属性路径是否存在(如
playerStats.equipment.weapon) - 可选属性(
String?)的访问 - 数组元素类型
7️⃣ 实时诊断与快速修复
🔹 检测的错误类型
| 错误类型 | 示例 | 快速修复 |
|---|---|---|
| 类名拼写错误 | PlayerStat.add_gold(100) |
建议:PlayerState |
| 方法名拼写错误 | PlayerState.add_gld(100) |
建议:add_gold |
| 参数数量错误 | PlayerState.add_gold() |
自动填充必需参数 |
| 参数类型错误 | add_gold("100") |
转换为 int("100") |
| 段落未定义 | => undefined_title |
建议创建段落或纠正拼写 |
🔹 拼写纠正算法
使用 Levenshtein 编辑距离算法,智能建议相似的类名/方法名:
# ❌ 错误
do PlayrState.add_gold(100)
^^^^^^^^^
未找到类 'PlayrState'
# 💡 快速修复建议:
# 1. 将 'PlayrState' 改为 'PlayerState'
# 2. 将 'PlayrState' 改为 'PlayerStat'
🔹 类型转换
自动建议类型转换:
# ⚠️ 警告
do PlayerState.add_gold("100")
^^^^^
参数类型不匹配:期望 'int',实际 'String'
# 💡 快速修复:
# 转换为 int 类型: int("100")
8️⃣ 文案导出
🔹 导出格式
右键菜单 → Dialogue: 导出文案,支持:
- JSON(格式化): 适合阅读和编辑
- JSON(紧凑): 适合程序读取
- CSV: 可用 Excel 打开
- Markdown: 表格格式
🔹 导出内容
[
{
"id": "DLG_0001",
"type": "character",
"speaker": "NPC",
"text": "你好,欢迎!",
"rawText": "你好,[wave]欢迎[/wave]![#happy]",
"line": 5,
"tags": ["happy"],
"hasInlineCode": false
},
{
"id": "DLG_0002",
"type": "narration",
"text": "这是一段旁白。",
"rawText": "这是一段旁白。",
"line": 6,
"tags": [],
"hasInlineCode": false
}
]
🔹 台词 ID 管理
右键菜单 → Dialogue: 为所有台词添加 ID
# 自动添加 ID
NPC: 你好! [ID:A1B2C3D4E5F6]
Player: 你好。 [ID:123456789ABC]
# 清除 ID
右键菜单 → `Dialogue: 清除所有台词 ID`
9️⃣ 代码折叠
🔹 自动折叠段落
从 ~ title 折叠到最后的 =>:
~ start # ← 点击折叠图标
NPC: 你好!
- 选项1 => a
- 选项2 => b
=> END # ← 折叠到这里
🔹 自定义区域
使用 #region / #endregion:
#region 第一章对话
~ intro
...
~ ending
...
#endregion
#region 战斗对话
~ battle_start
...
#endregion
⚙️ 配置选项
完整配置示例
{
// ========== 全局类配置 ==========
"dialogue.diagnostics.globalClasses": [
"PlayerState",
"AudioManager",
"SaveManager"
],
// ========== 全局变量配置 ==========
"dialogue.diagnostics.globalVariables": {
"playerName": {
"type": "String",
"comment": "玩家名"
},
"playerStats": {
"type": "Dictionary",
"schema": {
"hp": { "type": "int" },
"mp": { "type": "int" }
}
}
},
// ========== 自定义标签配置 ==========
"dialogue.diagnostics.customTags": {
"happy": {
"description": "快乐表情",
"category": "face",
"alias": ["开心"]
}
},
// ========== 标签分类配置 ==========
"dialogue.diagnostics.metadataCategories": {
"face": {
"icon": "😊",
"description": "表情"
}
},
// ========== 其他选项 ==========
"dialogue.diagnostics.enableCustomTags": true,
"dialogue.diagnostics.strictMode": false
}
❓ 常见问题
Q1: 补全列表中没有我的类?
A: 确保你的类使用了 class_name 声明:
# ✅ 正确
class_name PlayerState
extends Node
# ❌ 错误
extends Node
或者将类在全局挂载,然后重启 VSCode 或等待类缓存刷新。
Q2: 跨文件段落补全不生效?
A: 确保:
import语句正确(路径使用res://)- 打开过导入的
.dialogue文件(触发扫描) - 导入的文件中存在
~ xxx段落定义
Q3: 如何禁用某些检查?
A: 在 settings.json 中设置:
{
"dialogue.diagnostics.strictMode": false // 禁用严格模式
}
Q4: 私有成员(_ 开头)不显示?
A: 这是预期行为,符合 GDScript 的可见性规则。如果需要访问私有成员,直接输入完整名称即可(不会自动补全)。
Q5: 首次打开项目时补全很慢?
A: 扩展需要扫描所有 GDScript 文件构建类缓存,通常需要 2-5 秒。等待控制台输出 ✅ 类缓存初始化完成 后即可正常使用。
🛠️ 开发与贡献
环境设置
git clone https://github.com/hakubox/dialogue-godot-support.git
cd dialogue-godot-support
npm install
调试
- 在 VSCode 中打开项目
- 按
F5启动扩展开发主机 - 在新窗口中打开 Godot 项目测试
打包
npm run package
# 生成 dist/dialogue-godot-support-x.x.x.vsix
贡献指南
欢迎提交 Issue 和 Pull Request!请确保:
- 代码符合 TypeScript 规范
- 添加必要的注释
- 测试新功能
📄 许可证
MIT License - 详见 LICENSE 9 文件
🙏 致谢
📧 联系方式
- GitHub Issues: 提交问题 13
- 作者: hakubox
- 邮箱: hakubox@outlook.com
如果这个扩展对你有帮助,请给个 ⭐️ Star!