KonadoScript 基础:对话与语音
学习剧本文件规则与对话行语法,掌握三种说话者形式与打字速度语音标签
动作游戏几何构成(speed-rouge)的剧情里,最常出现的一类行不是指令,而是对话:角色说一句话,屏幕下方打字机逐字浮出,配音同步播放。写这些行的人是编剧,不是程序员——KonadoScript 就是为这个分工设计的创作语言:一行文本就是一句对话,不需要任何编程知识;需要演出变化时,再往行里添加指令。上一篇我们知道了 .ks 剧本会在导入或保存时被编译成虚拟机指令,本篇回到创作的起点,把你在 KonadoScript 里写得最多的一类行——对话行——彻底讲清楚:它的语法结构、说话者的三种书写形式、2.8 新增的命名参数,以及如何给一句话挂上语音。读完你就能写出带旁白、带配音、带打字节奏的第一幕剧情。
设计理念:故事内容与程序逻辑分离
KonadoScript 的每一条设计都围绕”故事内容与程序逻辑分离”这个核心理念展开:
- 编剧无需编程知识。对话就是一行文本,指令是少量固定的单词,编剧可以完全不看 GDScript。
- 资源通过标识符引用与脚本解耦。剧本里写的是 alice 这样的标识符,至于 alice 对应哪张贴图、哪个场景,由资源列表(例如角色列表 character_list)决定。换立绘不需要改剧本。
- 模块化指令集。登场、切背景、运镜、变量、选项各自是指令,按需组合,互不干扰。
- 文本格式跨平台、兼容 Git。纯文本的 .ks 可以用任何编辑器编写,Git 的逐行对比能清楚看到每次改动,方便团队协作。
文件规则只有两条:后缀为 .ks;编码为 UTF-8。UTF-8 不是可选项——无论手写还是从别处粘贴,保存成其他编码都可能让中文对话出问题,请在编辑器里确认编码设置。
对话行的语法结构
对话行的完整语法结构如下:
[说话者] "对话文本" [配音标签] [参数=值 ...]方括号表示该部分可以省略,也就是说最简单的一句对话只需要说话者与文本。逐段拆开:
- 说话者:三种形式之一,见下一节。
- 对话文本:角色要说的话,按语法约定写在英文双引号内。
- 配音标签:可选,写一个语音标识符,由 voice_list 资源解析成实际音频。
- 参数=值:可选的命名参数,例如 [speed=1.5],这是 2.8 新增的特性。
说话者的三种形式
形式一:裸演员 ID
alice "你好,我叫爱丽丝!"alice 是在角色资源列表(KonadoCharacterList)中注册的演员 ID。运行时系统根据 ID 找到对应角色资源,署名区显示角色名。这是最常用的形式,适合所有”有立绘、有档案”的角色。
形式二:变量说话者
set $speaker "alice"
$speaker "今天由变量决定谁在说话。"
set %current_speaker "alice"
%current_speaker "持久变量同样可以作为说话者。"说话者位置也可以写 开头是临时变量,% 开头是持久变量,变量系统的完整规则见本模块后续的变量篇,这里先认识写法。
形式三:带引号署名
"narrator" "暴风雨越来越猛烈了..."说话者位置写一段带英文双引号的纯文本,它不对应任何演员资源,署名区原样显示这段文字,适合旁白(narrator)与不需要立绘的临时发言。这种署名支持插值——可以在其中引用变量,运行时替换为实际值;写成空字符串则会完全隐藏署名,做纯画面叙事时很有用。
命名参数:speed 与 interval
2.8 为对话行新增了命名参数(named parameters)特性,首先提供的是两个控制打字速度的参数:
- speed:本句的打字速度倍率,必须大于 0。1.5 表示比平时快一半,2.0 表示两倍速。
- interval:每个字符的打字间隔秒数,数值越小打得越快。
两者不能同时使用:给了 speed 就不要再给 interval。写法放在行尾的方括号中:
alice "这一句会显示得更快。" [speed=1.5]
alice "这一句每个字符间隔 0.1 秒。" [interval=0.1]使用直觉:抢话、惊呼、紧张台词用 speed 提速;一句慢慢浮现的低语用更长的 interval 放慢节奏。
给对话挂语音
在对话行的配音标签位置写一个语音标识符,播放时由 voice_list 资源解析为实际音频:
Kona "……" voice_01语音成功播放时,对话框默认会显示这段音频的播放进度;如果你不想要这个进度显示,可以在 KonadoDialogueBox 的 show_voice_progress 属性中关闭。
两件配套的事值得知道:其一,语音标识与演员 ID 一样是”剧本里写名字、资源里给内容”的解耦设计,配音换文件不用动剧本;其二,插件自带语音进度显示模板 voice_progress_display.tscn,默认对话框的进度显示正是基于这套能力实现的。配音量大时,建议把语音文件命名与标识符对应好,便于批量维护。
官方示例逐行讲解
下面是官方文档中的完整示例,一次用齐了本篇所有知识点:
alice "你好,我叫爱丽丝!" alice_intro_01
alice "这一句会显示得更快。" [speed=1.5]
"narrator" "暴风雨越来越猛烈了..."
set $speaker "alice"
$speaker "今天由变量决定谁在说话。"
set %current_speaker "alice"
%current_speaker "持久变量同样可以作为说话者。"
set $guest_index 2
"访客 $guest_index" "很高兴见到你。"逐行看:
- 第 1 行:裸演员 ID 加配音标签。alice 说话,行尾的 alice_intro_01 是语音标识,由 voice_list 解析播放。
- 第 2 行:同一说话者继续说,speed=1.5 让这句打字更快。
- 第 3 行:带引号署名 “narrator”,纯文本旁白,不依赖任何演员资源。
- 第 4 行:set 指令给临时变量 $speaker 赋值 “alice”。
- 第 5 行:$speaker 作为说话者,运行时替换为 alice。
- 第 6 行:set 给持久变量 %current_speaker 赋值。
- 第 7 行:持久变量同样可以担任说话者。
- 第 8 行:临时变量 $guest_index 存入数字 2。
- 第 9 行:署名 “访客 $guest_index” 中发生插值,玩家实际看到”访客 2”。
其中 set 的”指令 变量 值”写法只是变量操作的一种形态,变量系统会在后续篇章完整展开。
控制对话框显隐:showtextbox 与 hidetextbox
hidetextbox 0.5
"narrator" "对话框隐藏后,画面完全交给立绘与背景。"
showtextbox 0.5
alice "我回来了。"showtextbox 与 hidetextbox 分别显示和隐藏对话框,后面的 duration 参数决定行为:
- 省略或 0.0:立即显示或隐藏,不等待。
- 大于 0:播放淡入或淡出动画,并等动画完成后再继续下一行。
- hidetextbox 完成后还会清除角色名与文本内容,重新显示时是一块干净的面板。
典型用途:全屏立绘鉴赏、章节标题、需要玩家看清画面的关键桥段。
常见误区与检查清单
新手最常在以下四处踩坑,写完剧本照着检查一遍能省掉大部分报错:
- 编码不是 UTF-8。从 Word、聊天窗口粘贴文本后另存时,编码可能被改成 GBK 之类,中文对话会出问题。永远确认 .ks 文件以 UTF-8 保存。
- speed 与 interval 同时出现。两者互斥,给了 speed 就删掉 interval,反之亦然;speed 还必须大于 0。
- 引号用了中文全角引号。对话文本、署名、选项内容约定的都是英文双引号,全角引号不会被按语法解析。
- 以为 hidetextbox 只是”看不见”。它完成后会清除角色名与文本,如果后续想保留上一句内容再隐藏,应使用 KonadoDialogueBox 的 hide_dialogue_box 系列方法(保留内容、暂时隐藏),而不是剧本里的 hidetextbox。
自检问题
- 三种说话者形式各适合什么场景?(裸 ID 给正式角色;变量说话者给”运行时才知道谁在说”的桥段;带引号署名给旁白与无立绘发言)
- 想让一句台词比平时快一半,写什么?speed 与 interval 能同时写吗?([speed=1.5];不能,两者互斥)
- 语音换了一个音频文件,剧本需要改吗?(不需要,剧本只写标识符,voice_list 负责解析——这正是内容与资源解耦的意义)
- hidetextbox 之后重新显示,上一句台词还在吗?(不在,它完成了清除;要保留内容请用代码侧的 hide_dialogue_box 系列方法)
动手实践
任务一:三句对话与变速。 写一段三句对话,让中间一句加速播放,保存为 UTF-8 的 .ks 文件并在模板场景中播放验证。提示:想清楚”加速”用 speed 还是 interval——两者只能选一。
任务二:旁白转场。 写一段”对话框消失 -> 纯旁白 -> 对话框回来 -> 角色说话”的四行剧本,旁白期间画面完全交给背景。提示:显隐指令带 duration 时会等动画播完再走下一行,利用这一点安排节奏。
任务三:变量说话者。 用一个 $ 临时变量在两句话之间切换说话者(比如 alice 换成 bob),并把访客编号插值进带引号署名里。提示:先 set 变量再把它放在说话者位置;署名插值参考官方示例的第 8、9 行。
先自己写,再对照参考实现:
任务一参考实现
alice "第一句,正常速度。"
alice "第二句,加速播放。" [speed=2.0]
alice "第三句,恢复正常。"启用插件后双击 .ks 文件即可在 Godot 内置的 KonadoScript 编辑器中打开(保存时自动重新编译运行时数据),再通过模板场景播放验证,观察中间一句的打字速度差异。
任务二参考实现
hidetextbox 0.5
"narrator" "对话框退场,整个画面只剩雨夜的街灯。"
showtextbox 0.5
alice "我回来了。"两个 0.5 让淡出与淡入各占半秒,播放器会等动画完成再继续——不写 duration 则瞬时切换,节奏会显得突兀。注意 hidetextbox 完成后内容已被清除,所以 alice "我回来了。" 出现时面板是干净的,不会残留旁白文字。
任务三参考实现
set $who "alice"
$who "这句由 alice 说。"
set $who "bob"
$who "同一行写法,说话者换成了 bob。"
set $guest_index 7
"访客 $guest_index" "而这一句由插值出来的署名发言。"三个知识点在一个剧本里闭环:变量决定说话者(运行时替换)、同一行语法适配不同说话者、带引号署名支持插值。故意把 $who 的值设成未注册的演员 ID(如 "nobody")跑一次,观察运行时报什么错——这能帮你建立”剧本标识符 -> 资源列表”的排错直觉。
下一步
- 让说话的人有立绘、让画面有背景与运镜:舞台与运镜(040 篇);
- 剧本里用变量与选项让剧情分岔:变量、选项与分支(050 篇);
- 剧情里”打字快慢”之外更细的演出控制:进阶指令(060 篇);
- 动作与剧情共存的实例:https://github.com/fanquanpp/geometric-construct