122 - API文档汉化 - 会说话的卡牌

Updated a week ago

会说话的卡牌

本API支持从零开始创建新的会说话的卡牌,无需加载自定义Unity预制体或其他类似资源!

您只需创建一个实现ITalkingCard接口的类,该接口包含以下字段:

字段 类型 说明
CardName string 现有卡牌的名称
Emotions List<EmotionData> 会说话卡牌的情绪表现
FaceInfo FaceInfo 卡牌面部信息:眨眼频率和语音
DialogueAbility SpecialTriggeredAbility 控制卡牌对话的特殊能力

之后,您只需通过TalkingCardManager.New<T>()方法注册您的会说话卡牌:

TalkingCardManager.New<ExampleClass>();

另外,从上表最后一项可以看出,您需要创建一个新的SpecialTriggeredAbility来控制卡牌对话。

别担心,我会详细说明操作步骤!

幸运的是,本API已支持创建新的特殊能力。此外,您无需从头开始:基础游戏已定义了抽象类,创建会说话卡牌的特殊能力时应继承这些类:

章节 应继承的类
第一幕 PaperTalkingCard
第三幕 DiskTalkingCard

额外说明:为简化第一幕会说话卡牌的创建流程,我定义了一个继承自PaperTalkingCard的抽象类,它实现了ITalkingCard接口并包含一些幕后调整!这个类名为CustomPaperTalkingCard

您只需创建一个继承自CustomPaperTalkingCard的类并实现其抽象字段:

public class ExampleTalkingCard : CustomPaperTalkingCard
{
    public override string CardName => "example_ExampleCard";
    public override List<EmotionData> Emotions => new List<EmotionData>()
    {
        new EmotionData(emotion: Emotion.Neutral,
            face: "Example_Face.png",
            eyes: ("Example_EyesOpen.png", "Example_EyesClosed.png"),
            mouth: ("Example_MouthOpen.png", "Example_MouthClosed.png"),
            emission: ("Example_EyesOpenEmission.png", "_"))
    };
    public override FaceInfo FaceInfo => new FaceInfo(blinkRate: 1.5f, voiceSoundPitch: 1.1f);
    
    public override SpecialTriggeredAbility DialogueAbility => dialogueAbility;
    
    private SpecialTriggeredAbility dialogueAbility = SpecialTriggeredAbilityManager.Add(
            guid: Plugin.PluginGuid,
            abilityName: "ExampleDialogueAbility",
            behavior: typeof(ExampleTalkingCard)).Id;

    public override string OnDrawnDialogueId => "Example_OnDrawn";

    public override string OnPlayFromHandDialogueId => "Example_OnPlayFromHand";

    public override string OnAttackedDialogueId => "Example_OnAttacked";

    public override string OnBecomeSelectablePositiveDialogueId => "Example_OnSelectedPositive";

    public override string OnBecomeSelectableNegativeDialogueId => "Example_OnSelectedNegative";

    public override Dictionary<Opponent.Type, string> OnDrawnSpecialOpponentDialogueIds => new Dictionary<Opponent.Type, string>();
}

然后通过以下方式注册新卡牌:

TalkingCardManager.New<ExampleTalkingCard>();

注意CustomPaperTalkingCard仅适用于第一幕卡牌。若要创建第三幕会说话卡牌,需直接继承DiskTalkingCard!

下文将深入解析会说话卡牌一些重要的点。

EmotionData

EmotionData类用于存储角色某情绪状态下的精灵图。其构造函数可接受Unity Sprite对象或图像路径字符串。

构造函数参数说明:

参数 说明
emotion 选择的情绪类型
face 角色面部精灵图
eyes 角色眼睛精灵图对(睁开/闭合)
mouth 角色嘴巴精灵图对(张开/闭合)
emission 角色眼睛发光效果精灵图对(睁开/闭合)

如需使用空白肖像纹理,可调用TalkingCardManager.EmptyPortrait

字符串构造函数的空纹理简写:在对应参数位置使用"_"。

下文章节将介绍如何在卡牌对话中应用情绪。

FaceInfo

FaceInfo类包含卡牌面部信息:眨眼频率、语音音高及语音类型。

构造函数参数说明:

参数 类型 说明
blinkRate float 眨眼频率(秒)
voiceId string 语音类型(下文详解)
voiceSoundPitch float 语音音高调节
customVoice string 自定义语音路径(下文详解)

“voiceId”仅限以下三种:

  1. female1_voice
  2. cat_voice
  3. kobold_voice

游戏中多数卡牌使用第一种并通过音高调节实现差异化。

自定义语音

您可通过“customVoice”参数指定音频文件路径来使用自定义语音。支持MP3/WAV/OGG/AIFF格式。

建议使用极短的元音音频,因为该声音会快速重复播放。

若设置了“customVoice”,则“voiceId”参数内容将被忽略。

对话事件

查看示例后,您可能疑惑:“这些DialogueId是什么?如何创建自定义对话事件?”

下面将详细说明:

对话触发器

会说话卡牌可响应多种游戏事件。如需让卡牌响应特定事件,可重写对应属性并返回新对话事件的ID。

部分抽象属性必须实现:OnDrawnDialogueIdOnPlayFromHandDialogueIdOnAttackedDialogueIdOnBecomeSelectablePositiveDialogueIdOnBecomeSelectableNegativeDialogueId

以下是可重写的完整触发器列表(为简洁省略“DialogueId”后缀):

触发器 说明
OnDrawn 抽牌时触发
OnPlayFromHand 出牌时触发
OnAttacked 受攻击时触发
OnBecomeSelectablePositive 成为增益效果可选目标时触发
OnBecomeSelectableNegative 成为减益效果可选目标时触发
OnSacrificed 被献祭时触发
OnSelectedForDeckTrial 在牌组试炼节点被选中时触发
OnSelectedForCardMerge 在印记节点接收印记前触发
OnSelectedForCardRemove 被选为移除目标时触发

此外,OnDrawnSpecialOpponentDialogueIds字典可为特定头目战添加抽牌特殊对话:

public override Dictionary<Opponent.Type, string> OnDrawnSpecialOpponentDialogueIds => new Dictionary<Opponent.Type, string>()
{
    { Opponent.Type.ProspectorBoss, "Example_TalkAboutProspector" }
};

创建对话事件

通过DialogueManager.GenerateEvent()方法创建:

DialogueManager.GenerateEvent(
    pluginGUID: Plugin.PluginGuid,
    name: "Example_OnPlayFromHand",
    mainLines: new List<CustomLine>() { "这是主对话线。" },
    repeatLines: new List<List<CustomLine>>()
    {
         new List<CustomLine>() { "这是重复对话线1!" },
         new List<CustomLine>() { "这是重复对话线2!" }
    }
);

参数说明:

字段 说明
pluginGUID 模组GUID
name 事件名称(用于引用)
mainLines 首次触发时播放的对话
repeatLines 后续触发时轮播的多组对话

对话代码

游戏对话事件支持丰富的对话代码,能为对话注入活力!

以下是与会说话卡牌最相关的代码:

等待([w:])

最常用的对话代码。格式[w:x]表示暂停x秒后继续播放。

示例:

"你好。[w:1]最近怎样?"

“你好。”说完后等待1秒才继续。

等待时间支持小数(如[w:0.2])。不建议低于0.1秒。

颜色([c:])

[c:X]可改变文本颜色,[c:]恢复默认。

示例:

"[c:R]红色文本[c:]默认文本"

颜色代码对照表:

代码 颜色
B 蓝色
bB 浅蓝
bG 浅金
blGr 浅柠檬绿
bR 浅红
brnO 棕橙
dB 深蓝
dlGr 深柠檬绿
dSG 深海沫绿
bSG 荧光海沫绿
G 金色
gray 灰色
lGr 柠檬绿
O 橙色
R 红色

自定义颜色

支持十六进制颜色码(需包含#):

"你肯定...[w:0.4][c:#7f35e6]很困惑[c:][w:1]"

莱西对话

[leshy:x]代码让莱西说x内容。示例:

"我们完了。[leshy:安静。][w:2]"

在这个例子中,角色说了“我们完了。”,然后莱西紧接着说了“安静。”。这段文字在屏幕上停留了2秒。

注意事项:

  1. 莱西台词无需引号
  2. 可结合等待代码使用

在对话中使用情绪

通过[e:x]代码切换情绪状态,x为情绪名或对应数字。情绪名不区分大小写。示例:

"[e:Anger]我很生气。"
"[e:anger]我很生气。"
"[e:AnGeR]我很生气,我的键盘也在搞我。"

如果你愿意,你可以使用与情绪的数字ID来代替它的名称!这是完全有效的,例如:

"[e:2]同样表示愤怒。"