在线表情
使用 MCE Online 时,玩家显示的情绪气泡其他玩家也能看到:按下 F3,在每一个把你纳入范围的屏幕上,你的化身头顶都会弹出一个爱心。
表情与位置更新走同一场实时对局(参见世界同步)。它们不需要额外的服务、RPC 或数据库:表情是一条被转发后即被遗忘的微小消息。
适用于 Pro 和 Source 层级。
流程
sender Nakama world match receiver
────── ────────────────── ────────
F3 pressed
PlayerEmotes.Played("heart")
OnlineEmoteRelay ──opcode 3──▶ relays it as it comes ──opcode 3──▶ WorldSyncService.HandleEmote
{"e":"heart"} (no inspection) OnlineEmotes.TryRead (checks the name)
OnPlayerEmote(userId, "heart")
PlayerSpawnManager.ApplyEmote
OnlineEmotes.ShowOver(avatar, "heart", gameSet)
- 发送方。 本地玩家的快捷键触发
PlayerEmotes.Played(本地代码监听的同一个事件)。在世界同步服务运行期间,OnlineEmoteRelay会挂接到该事件上,并仅在服务正 在运行、已连接且已加入世界对局时,把气泡的名称发送到世界对局。重复挂接不会重复发送。 - 服务器。 世界对局把 opcode
3原样转发给其他玩家,就像地图切换(2)和跟随者(4)事件一样。它不解析消息体。 - 接收方。
WorldSyncService严格地读取消息,触发OnPlayerEmote(userId, balloonName),然后PlayerSpawnManager在该玩家的化身头顶绘制气泡 —— 前提是该化身已生成,也就是说只有处于你兴趣区域内的玩家才能看到。
消息
| Opcode | 3(WorldSyncService.OP_EMOTE) |
| 消息体 | {"e":"heart"} —— 一个 JSON 对象,气泡名称放在 e 中 |
| 构造方法 | OnlineEmotes.Payload(name) |
安全:对端无法让你绘制任何东西
对端发来的是来自外部的文本,因此永远不会被信任:
- 名称在被任何东西使用之前,由
OnlineEmotes.IsValidName检查:小写字母、数字和下划线,最多OnlineEmotes.MaxNameLength(32 )个字符。对于其他任何内容 —— 格式错误的 JSON、空名称、过长的名称 ——OnlineEmotes.TryRead(json, out name)都返回false,WorldSyncService会记录Bad emote from <user>: not a balloon name.并丢弃它。 - 绘制的始终是你的游戏或引擎已经拥有的、同名的那个气泡(
EmotionBalloonSet.Resolve)。消息携带的是名称,绝不是精灵。没人拥有的名称什么也不会绘制。
这也是气泡无需内容同步的原因:如果你的游戏用自己的图案替换了 heart,你的游戏的每位玩家看到的都是你的爱心。
观察表情
| 成员 | 触发时机 |
|---|---|
WorldSyncService.OnPlayerEmote | 收到一个有效的表情:(userId, balloonName) |
OnlineEmotes.Shown | 已在远程化身头顶绘制了气泡且已就位:(balloonName, avatarTransform)。抛出异常的监听器会被记录,不会中止气泡。 |
using OpenMon.MCE.Online.World;
OnlineEmotes.Shown += (name, avatar) =>
Debug.Log($"{avatar.name} shows '{name}'.");
参考
| 类型 | 命名空间 | 作用 |
|---|---|---|
OnlineEmotes | OpenMon.MCE.Online.World | 消息格式、名称校验、ShowOver(Transform avatar, string name, EmotionBalloonSet game)、Shown 事件 |
OnlineEmoteRelay | OpenMon.MCE.Online.World | 把 PlayerEmotes.Played 送到套接字 |
WorldSyncService | OpenMon.MCE.Online.World | OP_EMOTE、OnPlayerEmote |
PlayerSpawnManager | OpenMon.MCE.Online.World | 在远程化身头顶绘制气泡 |