articy:draft 3 使用中需要注意的点

作者:最後
2022-01-11
9 8 0

使用 unity 制作对话相关的文本时,想要让文案的归文案,程序的归程序,因此需要找一个能方便制作游戏对白的软件/unity 插件,而我的需求如下:

  • 具有可视化的对白流程结构显示,便于制作及管理对白
  • 产出的文本能够很方便的导入到 unity 中,在 unity 中也不需要进行多么复杂的设置即可使用
  • 软件使用费用较低,最好是一次性付费

依据上述要求,我最终选定了 articy:draft 3 这个软件(下文简称 articy),虽然软件本身是订阅制的,但是 steam 版是一次性买断的,缺点是没有订阅版的多人协作功能,但是自己用完全够了。在跟着官方手册学习的过程中,因为自己的粗心也踩了很多坑,同时也积累了一些在使用过程中需要小心注意的点,以作记录,需要注意的是,这些小知识是建立在已经有一定程度的使用经验上,且希望将其与 unity 一块使用,如果是刚上手 articy,建议还是先跟着官方手册学习一遍(奶牛关上已经有人将之翻译为中文)。

注意点

1、在代码中,所有需要读取到的属性、实体的数据,均需要用到技术名称,因此,Articy 的所有实体的技术名称需要规划好,到时候统一进行维护修改。


2、ArticyFlowPlayer 组件负责控制对话流程,要使用该组件需要一个配套脚本来实现 OnFlowPlayerPausedOnBranchesUpdated 接口,两个接口分别负责对话的配置显示以及选项的处理,除此之外,组件还需要配置 StartOn 属性,来指定要从哪里开始对话流程。


3、每次在 articy 中重命名了变量名,导入到 unity 后,需要在 unity 中找到 ArticyDataBase 对象点击重新导入数据按钮才能让 unity 识别到新的变量名(当数据库读不到数据时才会出现重新导入按钮,平时不用管)。


4、当需要获取实体对象的模板数据时,需要注意对应的实体模板参数的技术名称在 模板设计->实体 文件夹中

在代码中可以直接使用模板的技术名称来获得拥有该模板参数的对象

DefaultMainCharacterTemplate ent = ArticyDatabase.GetObject<DefaultMainCharacterTemplate>("PC_Jason");
Debug.Log(ent.DisplayName);

注:官方手册中的模板也指这里,而不是下面的特性,需要分清楚,特性是不能直接作为关键字使用的,而实体模板参数可以!!!


5、Articy 中对象模板的下拉列表属性也可以通过第 4 点的方式来获得,不过需要注意的是,直接输出值是输出的对应项的技术名称

Debug.Log(ent.Template.Character.Taste);

需要使用 GetDisplayName() 方法来获得其显示名称

Debug.Log(ent.Template.Character.Taste.GetDisplayName());

这里是跟 Articy 软件中的下拉列表里的设置是一一对应的,因此建议技术名称也自己设置

此外,当需要修改值时,也可以直接修改,下拉列表在导入到 unity 时会自动生成对应的枚举类,因此可以直接使用

ent.Template.Character.Taste = Taste.__02;


6、ArticyObject 是一个基类,要获得对象的更多的属性数据,需要使用 as 关键字将其转换为对应的子类,在里面获得对应数据。比如要获取对象的显示名称(DisplayName),除了使用第 4 点的方法外,使用 as 转换的方法如下

ArticyObject ent2 = ArticyDatabase.GetObject("NPC_Freeman");
DefaultSupportingCharacterTemplate ent3 = ent2 as DefaultSupportingCharacterTemplate;
Debug.Log(ent3.DisplayName);


7、除了可以通过模板来获得对象数据,修改数据外,也可以通过特性来获得数据/修改数据,不过特性可以通过接口的方式来进行调用

var characterFeature = ent2 as IObjectWithFeatureDefaultBasicCharacterFeature;
characterFeature.GetFeatureDefaultBasicCharacterFeature().Age = 45;

其中接口后半部分的 FeatureDefaultBasicCharacterFeature 即为对应的特性的技术名称

也可以通过在模板对象中直接用 Get 指令获取/设置对应的特性

DefaultSupportingCharacterTemplate ent4 = ent2 as DefaultSupportingCharacterTemplate;
ent4.GetFeatureDefaultBasicCharacterFeature().Age = 66;
Debug.Log("现在年龄是"+ent4.GetFeatureDefaultBasicCharacterFeature().Age);

还可以使用 var 关键字来直接获得对应的特性对象

var ent3 = ArticyDatabase.GetObject<DefaultSupportingCharacterTemplate>("NPC_Freeman").GetFeatureDefaultBasicCharacterFeature();
Debug.Log("新的年龄是:"+ent3.Age);


8、当需要显示文本时,为了以后能做本地化,需要在对应的显示文本的对象上装上 ArticyLocaCaretaker 组件

当更换文本时,需要使用其 LocaKey 来进行更改

public void OnFlowPlayerPaused(IFlowObject aObject)
{
    //获取文本的方法 1
    var modelWithText = aObject as IObjectWithLocalizableText;
    if(modelWithText != null)
        {
            //将获得的文本 key 传递给对应的显示对象
            dialogText.LocaKey = modelWithText.LocaKey_Text;
        }
}

不过也可以使用 locaKey 字段来更改其值,但是还需要跟着 UpdateText 方法,才会使得文本对象的 text 更新,这里也可以在该更新方法中设定一些更新文本过程中需要做的事

public void OnFlowPlayerPaused(IFlowObject aObject)
{
    //获取文本方法 2,注意 locaKey 的首字母 l
    var dlgFragment = aObject as DialogueFragment;
    if (dlgFragment != null)
        {
            dialogText.locaKey = dlgFragment.LocaKey_Text;
            dialogText.UpdateText();
        }
}

因此在写代码时,需要注意检查 LocaKey 的首字母有没有大小写。


9、特别需要注意的是:ArticyLocalizationCaretakerTarget Component 选项必须要选择目标对象的 Text 组件,而不能直接将该目标对象直接拉进去,下图这样的拖法在游戏中是不会生效的

需要直接将 text 的组件拖进去才行,像下图这样,LocaKey 所对应的文本才能正确设置到目标对象的 Text 组件中


10、当所需要显示的内容为所有对象共有的属性(例如需要显示对象的文本时,而所有的对象,包括流片段,对话片段等都有文本 text 属性)时,可以使用接口来获得该属性,例如在通过接口获取的对话片段节点中

  • 获取发言者的接口是 IObjectWithSpeaker
  • 获取对话内容的接口是 IObjectWithLocalizableText
  • 获取菜单文本对应的接口是 IObjectWithLocalizableMenuText
  • 获取舞台指示的接口是 IObjectWithLocalizableStageDirections

一定要注意,如果打印出来的文本为空的话,除了检查目标组件项有没有填错外,还需要检查引用的接口以及在 Articy 中填对话片段节点时有没有填错。


11、当需要自定义输出的文本时,比如显示发言人名字+发言内容时,需要在流程控制脚本中增加监听事件

void Awake()
{
    //添加事件监听
    dialogText.localizedTextAssignmentMethod.AddListener(AssignDialogueText);
}

同时增加处理函数

/// <summary>
/// 对本地化文本进行处理,在文本前增加发言人名字
/// </summary>
/// <param name="aTargetComponent">所引用的 Target Component</param>
/// <param name="aLocalizedText">LocaKey 所对应的文本</param>
private void AssignDialogueText(Component aTargetComponent,string aLocalizedText)
{
    var text = aTargetComponent as ShowDialogueText;
    aLocalizedText = talkerName + ":" + aLocalizedText;
    text.SetShowText(aLocalizedText);
}

注意,该函数中的 2 个参数分别对应 Articy Localization CaretakerTarget ComponentLocaKey 所对应的文本,每当 Locakey 变化时,会自动调用该函数,会将之前自己填入的 Target Component 选项中的组件作为 Component 参数引入,再通过 as 关键字来转换为目标组件,从而调用该组件中的函数。

参考