情绪气泡与表情
情绪气泡是出现在角色头顶的小型动画气泡:训练师发现你时的感叹号、跟随者头 顶的爱心、困惑的 NPC 头顶的问号。MCE 自带 14 个气泡,都是每个游戏都有的原创绘制,并允许游戏在其之上加入自己的一套。
同样的气泡服务于四种不同的调用方:
| 调用方 | 如何请求气泡 |
|---|---|
| 玩家 | 功能键快捷键(F1 到 F12、Shift+F1、Shift+F2) |
| 脚本 | CommandGraph 中的 PlayEmotion 节点 |
| 跟随者 | 向你低吼时出现的爱心(MonsterFollowerController) |
| 其他玩家 | 在 MMORPG 层,显示在远程化身头顶的气泡:参见在线表情 |
它们全部按名称请求。
引擎自带的 14 个气泡
名称位于 EmotionBalloonNames(命名空间 OpenMon.MCE.Characters.Followers.Talk)。EmotionBalloonNames.All 按快捷键使用的顺序列出它们:
| 名称 | 快捷键 |
|---|---|
exclamation_mark | F1 |
question_mark | F2 |
heart | F3 |
music_note | F4 |
anger | F5 |
sweat_drop | F6 |
sleep | F7 |
happy | F8 |
sad | F9 |
shocked | F10 |
idea | F11 |
ellipsis | F12 |
sparkle | Shift+F1 |
determined | Shift+F2 |
引擎自带的这一套是位于 Resources/Characters/EmotionBalloons/DefaultEmotionBalloons 的 ScriptableObject,因此任何游戏无需连接任何东西即可找到它。
玩家快捷键
PlayerCharacter 在开始接收输入时会立即为自己添加一个 PlayerEmoteInput 组件。从那时起,上面的快捷键会在玩家头顶显示对应的气泡。
只有当玩家可以自由行动时,快捷键才会触发:
- 玩家没有在交互(没有对话、菜单或过场动画占用他),
- 游戏正在运行(时间缩放大于零),
- 上一个气泡已结束 —— 同一时间只有一个气泡。
每当本地玩家显示一个气泡时,就会以该气泡的名称触发 PlayerEmotes.Played。在线层正是通过这个事件得知需要通知其他玩家;你也可以监听它:
using OpenMon.MCE.Characters;
PlayerEmotes.Played += name => Debug.Log($"The player showed '{name}'.");
PlayerEmotes.NameForHotkey(functionKey, shift) 把一个按键映射到它的气泡名称(对 没有气泡的按键返回 null)。
从脚本显示气泡
在任意图中添加一个 PlayEmotion 节点(Create Command / Animations / PlayEmotion):
| 字段 | 含义 |
|---|---|
| Emotion | 气泡的名称(默认为 heart)。没人拥有的名称什么也不会播放,连声音也没有。 |
| Target | 显示气泡的角色。留空:运行该图的演员。 |
| On Player | 改为显示在玩家头顶。 |
| Wait | 让图等待,直到气泡消失(默认开启)。关闭时,图会在气泡播放期间继续运行。 |
PlayExclamation 是较早的、单一用途的同类节点:它在角色或玩家头顶显示感叹号,如果游戏的气泡集中有自己的感叹号,就使用游戏自己的。
跟随者的爱心
没有自己的对话表的跟随者(没有导入对话表的游戏),在你和它说话时一边低吼,一边在自己头顶显示引擎的爱心。代码可以向跟随者请求任意气泡:
// follower is the MonsterFollowerController of the player's follower
StartCoroutine(follower.ShowEmotion(EmotionBalloonNames.Sparkle));
使用你自己的气泡
游戏通过 Emotion Balloon Set(Create > MCE > Characters > Emotion Balloon Set)替换或扩展引擎的气泡:
| 字段 | 含义 |
|---|---|
balloons | 气泡列表:每个气泡有 name、它的 sprites、每次更新显示的精灵(spriteByUpdate)以及每次更新的跳跃高度(heightByUpdate)。时间线以每秒 60 次更新运行;16 个地图单位等于一个图块。 |
aliases | 气泡的另一个名称 —— 脚本对某个气泡的称呼,而卡带里叫法不同。 |
sound | 气泡弹出时发出的声音。留空:静音。 |
把这个集合赋给你的 MCESettings 资产的 Emotion Balloons 字段。当有东西请求气泡时,EmotionBalloonSet.Resolve(gameSet, name) 按以下顺序查找:
- 游戏自己的集合,按名称或别名;
- 引擎自带的集合(
EmotionBalloonSet.Default)。
因此,定义了 heart 的游戏在各处(快捷键、脚本、跟随者,以及其他玩家看到的气泡)都会得到它自己的爱心,而什么都没定义的游戏仍然拥有全部 14 个。
从卡带导入的游戏(参见导入的游戏与游戏配置文件)会得到由导入器构建的专属集合,游戏配置文件会把它赋给 MCESettings(并在还原配置文件时恢复原状)。
在任意身体之上
弹出组件(CharacterPopUpController)会在玩家和每个演员头顶绘制气泡。对于没有弹出组件的对象 —— 跟随者、其他玩家的化身、你自己的道具 —— 请使用 EmotionBubbleOverBody:
StartCoroutine(EmotionBubbleOverBody.Play(someTransform, balloon, clock: null));
它会在身体上挂一个临时对象,把它放在身体各精灵中最高的那个之上,相对所有精灵居中,并在每次更新时跟随气泡的跳跃。气泡结束后,该对象会被移除。没有可绘制内容的气泡,或没有精灵的身体,不会产生任何效果。
参考
| 类型 | 命名空间 | 作用 |
|---|---|---|
EmotionBalloonNames | OpenMon.MCE.Characters.Followers.Talk | 14 个名称和 All |
EmotionBalloonSet | OpenMon.MCE.Characters.Followers.Talk | 一组气泡、Default、Resolve、Find |
EmotionBubbleOverBody | OpenMon.MCE.Characters.Followers.Talk | 在任意身体之上绘制气泡 |
PlayerEmotes | OpenMon.MCE.Characters | 快捷键映射和 Played 事件 |
PlayerEmoteInput | OpenMon.MCE.Characters | 读取快捷键 |
CharacterPopUpController | OpenMon.MCE.Actors | PlayEmotion(name)、PlayBalloon(balloon, sound) |
PlayEmotion | OpenMon.MCE.Actors.CommandGraph.Animations | 脚本节点 |