本来说好的每周一更又鸽了…
今天来水一期,介绍一款很棒的剧情编排应用 YarnSpinner
。
# 介绍
YarnSpinner
是一款开源免费的剧情编排应用(或者说是一种用于剧情编排的标记语言)。
试想我们在开发游戏时,剧情有分支选择,有各种条件检查,如果我们全在代码中去判断和检查不仅繁杂而且非常麻烦,策划学习成本高,耦合性过强。你可能自己想出一套标记语言来表述剧情流程,但自己的力量毕竟是有限的,难免出现一些 bug 和坑。此时,不妨试试这款免费开源,多人共同维护的应用吧。
# 快速食用
# 代码式编辑
这里我使用 vscode 作为编辑器,下载一下插件:
我们先创建一个 .yarn
格式的文件,并写入以下内容:
title: cc
tags:
colorID: 0
position: 1,-22
---
Fasty97: Hi
PC: 你好?!
Fasty97: 我又回来了!
PC: 是忘了什么东西吗?
===
这是一段剧本最基本的格式(一个 yarn 文件至少包含一段剧本):
title: cc
tags:
colorID: 0
position: 1,-22
以上被称为一个剧本头,表示一段剧本,这些是一些剧本段的基本信息,其中title 必填,position 必填.position 为剧本段的标识符类似于 ID 一样的东西,不要重复。
# 在 unity 中使用
- 下载相关的 unity 支持包(官网有)
- 在场景中放入一个 Dialogue 预制体,预制体包含一个默认的设置示例。
- 创建一个脚本
- 设定好相关的资源和引用
- 运行游戏尝试按下空格键吧
# 脚本设定
using System; | |
using System.Collections.Generic; | |
using UnityEditorInternal; | |
using Yarn.Unity; | |
using UnityEngine; | |
using Yarn; | |
public class YarnTest : MonoBehaviour | |
{ | |
public DialogueRunner dr; | |
public YarnProgram scriptToLoad; | |
private void Start() | |
{ | |
// 注入对话资源 | |
dr.Add(scriptToLoad); | |
} | |
private void Update() | |
{ | |
if (Input.GetKeyDown(KeyCode.Space)) | |
{ | |
print("开始对话"); | |
// 开始一个对话 | |
dr.StartDialogue("cc"); | |
} | |
} | |
} |
# 使用自定义方法
我现在希望我第一次与角色交流时输出前 2 句,之后每次与角色交流只输出最后 2 句,这是一个游戏中常用的机制。但现在我们的对话只是按照流程依次执行,我们希望这个流程应该是能够动态控制的。
我们修改上面的 yarn 为:
title: cc
tags:
colorID: 0
position: 1,-22
---
<<if visited("cc") is false>>
Fasty97: Hi
PC: 你好?!
<<else>>
Fasty97: 我又回来了!
PC: 是忘了什么东西吗?
<<endif>>
===
可以看到这次我们使用 类似 if 语句的东西? 这是 yarn 中提供的一种语法模式,在这里我们会执行一个自定义的方法 visted 并将 "cc" 传入方法中,如果返回的结果是 false 就执行下面的语句块。
# 处理自定义事件
private HashSet<string> visitedNodes=new HashSet<string>(); // 已使用节点 | |
private void Start() | |
{ | |
// 注入对话资源 | |
dr.Add(scriptToLoad); | |
// 注入处理方法 | |
dr.AddFunction("visited",1,(Value[] parameters) => | |
{ | |
var nodeName = parameters[0]; | |
return visitedNodes.Contains(nodeName.AsString); | |
}); | |
// 绑定事件 | |
dr.onNodeComplete.AddListener((name) => { visitedNodes.Add(name); }); | |
} |
创建一个 HashSet 集合用于存放所有已经被使用过的 node,绑定一个 onNodeComplete 事件,这个事件有系统自动调用,在实现中为集合加入元素。
然后注入一个方法,第一个参数指定方法名(在 yarn 文件下的名称),第二个参数指定参数个数,第三个参数就是写入一个方法了,在方法中我们检查集合是否已经包含该值返回结果,一个自定义不可重复方法就处理好了。
使用相同的方法你还可以创建各种各样的方法在 yarn 中使用。
值得注意的是:
通过源代码我们可以知道,yarn 只支持以下几种数据类型。
case Value.Type.Number: | |
return (object) this.NumberValue; | |
case Value.Type.String: | |
return (object) this.StringValue; | |
case Value.Type.Bool: | |
return (object) this.BoolValue; | |
case Value.Type.Null: | |
return (object) null; |
# 相关链接
YarnSpinner 官网
YarnSpinner 在线编辑器
YarnSpinner github