UE5 SDK 开发指南
本文介绍如何在 UE5 项目中,于已进入房间后使用自定义消息或帧同步传输对战数据,覆盖 Android、iOS 和 Tap PC。
接入房间和连接前,请先完成快速入门。
状态同步
自定义消息同步
通过自定义消息在房间内同步玩家操作或状态,适合回合制、棋牌等对实时性要求不高的场景。流程可概括为:一方发送自定义消息,服务端转发后,房间内对应玩家在回调中解析并更新游戏状态。

适合的游戏类型包括:
- 棋牌类:五子棋、象棋、斗地主、麻将等
- 回合制:战棋、策略、回合制 RPG 等
- 休闲类:你画我猜、狼人杀、问答等
- 合作类:简单多人闯关、合作解谜等
发送自定义消息
该接口 和 更新玩家自定义状态(UpdatePlayerCustomStatus)、更新玩家自定义属性(UpdatePlayerCustomProperties)、更新房间信息(UpdateRoomProperties)共享每秒15次调用限制
开始游戏后,开发者通过将玩家操作数据封装为自定义消息内容同步给其他玩家,每秒最多 15 次,调用示例如下:
UTapBattle::SendCustomMessage(
CustomMsg, // 自定义消息,格式由开发者决定,必须是utf8字符串,最大2048字节
CustomMsgType, // 消息接收者类型。0:房间内所有玩家,不包括发送者;1:发送给指定玩家
PlayerIds, // 当type==1时有效,发送给该字段指定的玩家,最多20个ID
FTapOnBattleSuccess::CreateLambda([]()
{
UE_LOG(LogTemp, Log, TEXT("Send custom message success"));
// 发送者不会收到自己的消息,本地立即应用本次操作
}),
FTapOnBattleError::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Send custom message failed [%d]: %s"), Code, *Message);
}));
发送成功后,房间内对应玩家会通过 SDK 的 OnCustomMessageReceived 回调收到通知:
virtual void OnCustomMessageReceived_Implementation(
const FString& PlayerId, const FString& Message) override
{
// 校验并解析 Message,应用 PlayerId 的操作。
}
帧同步
帧数据同步
高实时性游戏,如格斗、MOBA、FPS,可使用帧同步:房主开始帧同步后,各端发送帧输入同步操作,房主停止帧同步或超时后结束本局。

- 开始对战:房主调用开始帧同步,房间内所有玩家进入帧同步状态
- 对战进行中:玩家发送帧输入进行帧数据同步
- 结束对战:房主调用停止帧同步,或超过 30 分钟后服务端强制结束
- 帧率为每秒 30 帧
- 开始帧同步后,最大支持 30 分钟,超过时间后服务端会强制停止帧同步
- 每个玩家每帧最多允许发送 5 次操作数据
开始帧同步
当房间内所有玩家状态就绪后,房主开启对战时,调用开始帧同步接口:
// 开始帧同步,仅房主可调用
UTapBattle::StartFrameSync(
FTapOnBattleSuccess::CreateLambda([]()
{
UE_LOG(LogTemp, Log, TEXT("Start frame sync success"));
// 等待 OnFrameSyncStarted 回调后再进入对战并发送帧数据
}),
FTapOnBattleError::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Start frame sync failed [%d]: %s"), Code, *Message);
}));
此时房间内所有玩家会通过 SDK 的 OnFrameSyncStarted 回调收到通知:
virtual void OnFrameSyncStarted_Implementation(const FTapBattleFrameSyncInfo& FrameSyncInfo) override
{
// 保存 RoomInfo、FrameSyncId、Seed、ServerTime,进入对战状态。
}
回调中会返回本次帧同步的基础信息 (FTapBattleFrameSyncInfo),主要包含房间信息(RoomInfo) 、随机种子(Seed)等
注意:开启帧同步后,禁止执行管理房间的所有操作,包括更新房间信息、更新玩家属性、离开房间、踢出玩家等,否则会收到错误码 26 的异常
发送玩家操作数据
对战过程中,玩家的操作数据可通过调用如下接口进行同步:
UTapBattle::SendFrameInput(
PlayData, // 玩家操作数据,utf8字符串格式,最大1024字节
FTapOnBattleSuccess::CreateLambda([]()
{
UE_LOG(LogTemp, Log, TEXT("Send frame input success"));
// 房间内玩家会通过 OnFrameReceived 收到本帧数据
}),
FTapOnBattleError::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Send input failed [%d]: %s"), Code, *Message);
}));
房间内其他玩家会通过 SDK 的 OnFrameReceived 回调收到通知:
virtual void OnFrameReceived_Implementation(const FTapBattleFrameData& FrameData) override
{
// 按 FrameData.Id 顺序处理 Inputs 中各玩家的数据。
for (const FTapBattlePlayerInputInfo& Input : FrameData.Inputs)
{
// Input.PlayerId 为玩家 ID,Input.Data 为操作数据,Input.ServerTime 为发送时间
UE_LOG(LogTemp, Log, TEXT("Frame %d player %s: %s"), FrameData.Id, *Input.PlayerId, *Input.Data);
}
}
回调中返回的参数 FrameData 会包括当前帧 ID 及多个玩家的多个操作数据,其中 Inputs 字段为玩家操作数据集合,集合中每条数据包含了玩家 ID、玩家操作数据、发送时间等信息。
停止帧同步
当房主结束对战时,开发者通过调用停止帧同步接口结束同步玩家数据:
// 停止帧同步,仅房主可调用
UTapBattle::StopFrameSync(
FTapOnBattleSuccess::CreateLambda([]()
{
UE_LOG(LogTemp, Log, TEXT("Stop frame sync success"));
// 停止发送帧数据,房间内玩家会通过 OnFrameSyncStopped 收到通知
}),
FTapOnBattleError::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Stop frame sync failed [%d]: %s"), Code, *Message);
}));
其他玩家会通过 OnFrameSyncStopped 回调收到通知:
virtual void OnFrameSyncStopped_Implementation(
const FString& RoomId, int32 FrameSyncId, int32 Reason) override
{
// Reason:0 为房主主动结束,1 为 30 分钟超时。停止发送帧输入。
}
随机数生成器
为保证玩家对战过程中,对于随机掉落物品或其他奖励的概率保持一致,不同玩家可使用该生成器生成相同序列的随机数。
建议在收到开始帧同步( OnFrameSyncStarted) 的回调中,使用返回的帧同步基础信息 FTapBattleFrameSyncInfo 参数的 Seed 字段来初始化随机数生成器。
#include "TapBattleRandomNumberGenerator.h"
// 使用帧同步回调返回的随机种子
int32 Seed = FrameSyncInfo.Seed;
// 创建生成器
auto Generator = UTapBattle::NewRandomNumberGenerator(Seed);
if (Generator)
{
// 生成随机数
const int32 Value = Generator->RandomInt();
// 当对战结束后或已确定不需要生成器时,可调用如下接口销毁随机数生成器
Generator->Free();
}