使用unity制作对话相关的文本时,想要让文案的归文案,程序的归程序,因此需要找一个能方便制作游戏对白的软件/unity插件,而我的需求如下:
- 具有可视化的对白流程结构显示,便于制作及管理对白
- 产出的文本能够很方便的导入到unity中,在unity中也不需要进行多么复杂的设置即可使用
- 软件使用费用较低,最好是一次性付费
依据上述要求,我最终选定了articy:draft 3这个软件(下文简称articy),虽然软件本身是订阅制的,但是steam版是一次性买断的,缺点是没有订阅版的多人协作功能,但是自己用完全够了。在跟着官方手册学习的过程中,因为自己的粗心也踩了很多坑,同时也积累了一些在使用过程中需要小心注意的点,以作记录,需要注意的是,这些小知识是建立在已经有一定程度的使用经验上,且希望将其与unity一块使用,如果是刚上手articy,建议还是先跟着官方手册学习一遍(奶牛关上已经有人将之翻译为中文)。
1、在代码中,所有需要读取到的属性、实体的数据,均需要用到技术名称,因此,Articy的所有实体的技术名称需要规划好,到时候统一进行维护修改。
2、ArticyFlowPlayer组件负责控制对话流程,要使用该组件需要一个配套脚本来实现OnFlowPlayerPaused和OnBranchesUpdated接口,两个接口分别负责对话的配置显示以及选项的处理,除此之外,组件还需要配置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、特别需要注意的是:ArticyLocalizationCaretaker的Target 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 Caretaker的Target Component和LocaKey所对应的文本,每当Locakey变化时,会自动调用该函数,会将之前自己填入的Target Component选项中的组件作为Component参数引入,再通过as关键字来转换为目标组件,从而调用该组件中的函数。
参考:
暂无关于此日志的评论。