打造从twine到dialogue system的工作流

Dialogue System是一个Unity的对话系统插件,如果你看到这篇文章,那么默认你已经对Dialogue System有所了解和使用,想要改善你的工作流。毕竟大段的剧情文本不可能每天开着unity来写吧。如果你还不了解Dialogue System,可以查看他们的官网和官方文档,链接我会附在文章的最后。
twine是什么
Twine是一个开源工具,用于创建交互式非线性故事。它允许用户通过简单的拖放界面和文本编辑来构建复杂的故事结构,而无需编程知识,并且最后可以帮助你生成自己的文字剧情游戏。
Twine支持多种故事格式,如Harlowe、SugarCube和Snowman等,每种格式都有其独特的语法和功能。用户可以根据自己的需求和喜好选择合适的故事格式。
而Harlowe是其中的一种故事格式,也是dialogue system支持的唯一一个故事格式,Harlowe同时也是一个标记语言,如果你会markdown的话,应该可以快速的理解并使用它。
为什么选择twine而不是Atricy:draft
其实类似的剧本创作工具有很多,比如Atricy:draft,YarnSpinner等等,这些工具我也尝试过,但是最终还是选择了Twine,原因如下:
- Twine相对而言更加轻量,Atricy:draft过重,需要管理的资产很多,上手门槛也比较高,需要理解Atricy:draft的各种概念,对于小型游戏或是简单的剧本创作来说,Twine更加简洁,让用户更加专注于故事编写。
- Twine本质上是一个web应用,所以可以在全平台上甚至是浏览器上运行,但是Atricy:draft只支持windows平台,这对于使用多设备办公的人或者是团队而言局限比较大。
- Twine是一个开源应用,使用它进行故事创作是免费的,你甚至可以fork它用于定制自己的版本,而Atricy:draft是闭源软件,并且会根据故事体量收取一定费用。
而YarnSpinner和Twine比较相近,但是YarnSpinner对于非线性叙事的组织结构的展示没有那么直观,更适合线性剧本的编写。
当然,大家可以根据自己的项目情况来选择合适的工具。
Harlowe语法速通
Harlowe的功能很多也很完善,提供了很多语法和宏命令,但是dialogue system目前只支持部分功能和语法,这里只指讲述这部分语法,如果想要学习完整的语法,可以查看Harlowe的文档 。
Link 链接
链接用于将一个段落连接到另一个段落,也可以用来为用户提供对话选项,比如:
1 | 这是一个故事的开头 |
->
前面的为链接文本,后面的为要链接到的段落,没有->
视为简写,则链接文本和链接到的段落一致。
得到的结果就会像这样
Actors 演员
如果要在对话中指定演员的话,在文本开头包含演员的名字即可:
1 | garate: 这是我说的一句话 |
在dialogue system中,需要提前在Actors中注册演员。
Cutscene Sequences 过场动画序列
需要在对话中使用过场动画序列时,直接在段落的最后写上序列的关键词Sequence
,之后所有的行都会被解释于序列命令:
1 | Hello, world! |
Script 脚本
要指定脚本字段,请在单独的行中写入Script
,后跟 Lua 表达式。例子:
1 | Script: |
Conditions 条件
要指定条件字段,请在单独的行中写入Conditions
,后跟 Lua 表达式。例子:
1 | Conditions: |
默认情况下,条件设置为 false 时阻止。要使条件直通,请将“(passthrough)”添加到条件:行。例子:
1 | Hello, world! |
描述
要指定描述字段,请在单独的行中写入Description
,然后接上你的描述:
1 | Hello, traveller. |
当然,这些命令都可以同时包含在一个段落中
宏
Harlow提供的宏命令很多,但是dialogue system目前仅支持(if:)
和(set:)
。
(if:) 条件宏
在条件宏中写出你的判断条件即可,if 宏仅支持结果为布尔值的表达时,比如:
1 | (if: $legs is 8)[You're a spider!] |
后面[]
中包含的则是判断通过后的内容。
在dialogue system中(if:)
宏中的内容会被写入到Conditions中。
(set:) 设置宏
设置宏用来为变量赋值,变量由$
开头,后为变量的名称:
1 | (set: $battlecry to "Save a " + $favouritefood + " for me!") |
在dialogue system中,变量需要提前注册在dialogue的变量数据库中。并且赋值语句会被添加到dialogue节点的Script中。
从twine到dialogue system
那么如何将在twine中写好的故事在dialogue system中应用呢?
导出故事为json格式
首先你需要在twine中安装Twison 故事格式,这个格式用于将故事作为json格式导出,用于导入到dialogue system或其它的引擎工具中。
在Twine-> Story Formats -> Add的安装输入框中填写下面的地址https://lazerwalker.com/twison/format.js
,点击添加,就会将Twison格式安装到Twine中。
然后准备好你写好的剧本,然后在Story->Details中将剧本的故事格式改为Twison,点击Build->play就会生成一个json字符串,将该字符串保存在JSON文件中。
将JSON导入到dialogue system中
在 Unity 中,选择Tools → Pixel Crushers → Dialogue System → Import > Twine 2 (Twison) 。这将打开一个类似于下图所示的窗口。
注意:注意:第一次选择此菜单项时,对话系统将询问您是否要启用 Twine 导入功能。单击启用。对话系统重新编译并启用 Twine 导入功能后,再次选择菜单项。
点击导入按钮,故事就会被导入到conversion中。
自定义功能扩展
可以看到,Dialogue System目前对Harlowe的支持不是特别全面,比如如果你想要设定dialogue节点上的其他选项,比如添加一些fields,目前就设置不了。
当然你可以通过联系Dialogue System官方,希望他们支持某些功能,但是反馈到开发,发行新版本的时间无疑很长,并且官方增加的功能或许也难以完全匹配我们的需求,所以我们可以选择自行进行功能扩展。
Dialogue System关于Twine故事导入到代码位于Assets\Plugins\Pixel Crushers\Dialogue System\Scripts\Importers\Twine\TwineImporter.cs
中,仔细阅读代码之后,发现其中的逻辑并不复杂,所以我们可以自行修改代码来进行功能扩展(修改之前先将原来的文件备份,防止改不回来)。
整个TwineImporter的整体逻辑为解析JSON->根据JSON内容动态创建dialogue node -> 将dialogue node组织为conversation。
首先我们来分析一下Twison格式的结构,一下是一段简单的Harlowe格式的故事片段
1 | 你好啊 |
得到的Twison格式内容如下:
1 | { |
结合代码,可以看到TwineImporter就是通过对passages节点的遍历和解析得到一个个dialogue节点的。那么了解大致流程之后,我们就可以在代码中自定义我们需要的功能了。
比如,我想要一个为dialogue节点设置Field字段,那么可以先规定语法,比如我们规定,在Fields
字段后的每一行为一个字段设置语句,=
前为字段名,后为字段的值。像这样:
1 | Fields: |
我们通过分析代码可以看到,像Sequence和Fields这些内容都是混在text中的,那么对text进行对应内容的提取即可。
在代码中的ExtractSequenceConditionsScriptDescription
函数中加入对Fields的提取代码即可
1 | ExtractBlock("Fields:", ref text, out fields); |
然后在ExtractBlock
函数中加入对应的提取代码:
1 | var fieldsIndex = FindBlockIndex(text, blockIndex, "Fields:"); |
这样我们就拿到了整个Fields字段的内容。
接下来需要对Fields进行解析,解析出字段名和字段值,并通过Dialogue System的API将Fields字段写入到dialogue节点中:
1 | if (fields != null && fields.Length > 0) { |
设置后的结果:
可以看到,field已经完美的被设置到了节点上。
TwineImporter并不复杂,通过分析之后,想要增加一些其他的你需要的功能肯定也不在话下了。
通过twine构建模板
Dialogue System对模板的支持较弱,仅支持同时存在一个模板。这让我们的开发效率大打折扣。
但是有了twine之后,我们就可以拥有多种模板。
节点模板
由于节点是纯文本内容,那么准备一个文档并通过伟大的复制粘贴即可使用你的模板。
对话模板
如果需要自定义的对话模板,那么你需要在Twine-> Set Story Library Folder中指定你的故事存放的文件夹。指定好之后,你在Twine中创建的每一个故事都会生成一个单独的html文件,通过伟大的复制粘贴你就可以使用你的自己的模板了。
多设备同步
由于Twine的web版本是将故事存储在浏览器的本地存储中,所以想要多设备同步故事内容或多人同步故事内容只能通过使用Twine的桌面版本,并通过版本管理工具如git来同步了。
相关链接
twinery官网
Harlowe的文档
Twison Github
Dialogue System文档
Dialogue System - Twine Import教程
yarnspinner 官网
Atricy:draft官网
- Title: 打造从twine到dialogue system的工作流
- Author: RaHsu
- Created at : 2025-01-07 11:31:08
- Updated at : 2025-01-07 11:35:09
- Link: https://www.rahsu.com/Tech/打造从twine到dialogue system的工作流/
- License: All Rights Reserved © RaHsu