本来说好的每周一更又鸽了…
今天来水一期,介绍一款很棒的剧情编排应用 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 中使用

  1. 下载相关的 unity 支持包(官网有)
  2. 在场景中放入一个 Dialogue 预制体,预制体包含一个默认的设置示例。
  3. 创建一个脚本
  4. 设定好相关的资源和引用
  5. 运行游戏尝试按下空格键吧

# 脚本设定

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 文件下的名称),第二个参数指定参数个数,第三个参数就是写入一个方法了,在方法中我们检查集合是否已经包含该值返回结果,一个自定义不可重复方法就处理好了。

visited效果

使用相同的方法你还可以创建各种各样的方法在 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

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Fasty 微信支付

微信支付

Fasty 支付宝

支付宝

Fasty 贝宝

贝宝