跳到主要内容

在线表情

使用 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)
  1. 发送方。 本地玩家的快捷键触发 PlayerEmotes.Played(本地代码监听的同一个事件)。在世界同步服务运行期间,OnlineEmoteRelay 会挂接到该事件上,并仅在服务正在运行、已连接且已加入世界对局时,把气泡的名称发送到世界对局。重复挂接不会重复发送。
  2. 服务器。 世界对局把 opcode 3 原样转发给其他玩家,就像地图切换(2)和跟随者(4)事件一样。它不解析消息体。
  3. 接收方。 WorldSyncService 严格地读取消息,触发 OnPlayerEmote(userId, balloonName),然后 PlayerSpawnManager 在该玩家的化身头顶绘制气泡 —— 前提是该化身已生成,也就是说只有处于你兴趣区域内的玩家才能看到。

消息​

Opcode3(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}'.");

参考​

类型命名空间作用
OnlineEmotesOpenMon.MCE.Online.World消息格式、名称校验、ShowOver(Transform avatar, string name, EmotionBalloonSet game)、Shown 事件
OnlineEmoteRelayOpenMon.MCE.Online.World把 PlayerEmotes.Played 送到套接字
WorldSyncServiceOpenMon.MCE.Online.WorldOP_EMOTE、OnPlayerEmote
PlayerSpawnManagerOpenMon.MCE.Online.World在远程化身头顶绘制气泡