跳到主要内容
版本:v3

多人在线对战入门教程 · C#

欢迎使用多人在线对战。本教程将通过模拟一个比较玩家分数大小的场景,来讲解 SDK 的核心使用方法。

安装

Play 客户端 SDK 是开源的,源码地址请访问 csharp-sdk

也可以直接下载 Release 版本

Unity 项目

SDK 可以通过 Unity Package Manager 导入或手动导入,二者任选其一:

  • UPM:请在项目的 Packages/manifest.json 中添加依赖项:

    "dependencies": {
    "com.leancloud.play": "https://github.com/leancloud/csharp-sdk-upm.git#play-2.3.0",
    }
  • 直接导入:解压下载的 LeanCloud-SDK-Play-Unity.zip,将 Plugins 目录拖拽至 Unity 工程。如果项目中已有 Plugins 目录,则合并至项目中的 Plugins 目录。

开启调试日志

为方便调试,你可以通过注册回调获取日志。在 Unity 中,可以参考如下设置:

// 设置 SDK 日志委托
LeanCloud.Common.Logger.LogDelegate = (level, log) =>
{
if (level == LogLevel.Debug) {
Debug.LogFormat("[DEBUG] {0}", log);
} else if (level == LogLevel.Warn) {
Debug.LogWarningFormat("[WARN] {0}", log);
} else if (level == LogLevel.Error) {
Debug.LogErrorFormat("[ERROR] {0}", log);
}
};

初始化

导入需要的命名空间

using LeanCloud.Play;
var client = new Client(
"your-client-id", // 游戏的 Client ID
"your-client-token", // 游戏的 Client Token
"tarara", // 设置用户 id
playServer: "https://your_server_url" // 游戏的 API 域名
);
  • 开发者中心 > 你的游戏 > 游戏服务 > 应用配置 可以查看游戏的 Client IDClient Token
  • API 域名在 应用配置 > 域名配置 > API 处查看,参考文档关于域名的说明。

连接多人对战服务器

try {
await client.Connect();
} catch (PlayException e) {
// 连接失败
Debug.LogErrorFormat("{0}, {1}", e.Code, e.Detail);
}

创建或加入房间

默认情况下 Play SDK 不需要加入「大厅」,即可创建 / 加入指定房间。

try {
await client.JoinOrCreateRoom(roomName);
} catch (PlayException e) {
// 创建或加入房间失败
Debug.LogErrorFormat("{0}, {1}", e.Code, e.Detail);
}

JoinOrCreateRoom 通过相同的 roomName 保证两个客户端玩家可以进入到相同的房间。请参考 开发指南 获取更多关于 JoinOrCreateRoom 的用法。

通过 CustomPlayerProperties 同步玩家属性

当有新玩家加入房间时,Master 为每个玩家分配一个分数,这个分数通过「玩家自定义属性」同步给玩家。 (这里没有做更复杂的算法,只是为 Master 分配了 10 分,其他玩家分配了 5 分)。

// 注册新玩家加入房间事件
client.OnPlayerRoomJoined += (newPlayer) => {
Debug.LogFormat("new player: {0}", newPlayer.UserId);
if (client.Player.IsMaster) {
// 获取房间内玩家列表
var playerList = client.Room.PlayerList;
for (int i = 0; i < playerList.Count; i++) {
var player = playerList[i];
var props = new PlayObject();
// 判断如果是房主,则设置 10 分,否则设置 5 分
if (player.IsMaster) {
props.Add("point", 10);
} else {
props.Add("point", 5);
}
player.SetCustomProperties(props);
}
var data = new PlayObject {
{ "winnerId", client.Room.Master.ActorId }
};
var opts = new SendEventOptions {
ReceiverGroup = ReceiverGroup.All
};
client.SendEvent(GAME_OVER_EVENT, data, opts);
}
};

玩家得到分数后,显示自己的分数。

// 注册「玩家属性变更」事件
client.OnPlayerCustomPropertiesChanged += (player, changedProps) => {
// 判断如果玩家是自己,则做 UI 显示
if (player.IsLocal) {
// 得到玩家的分数
long point = player.CustomProperties.GetInt("point");
Debug.LogFormat("{0} : {1}", player.UserId, point);
scoreText.text = string.Format("Score: {0}", point);
}
};

通过「自定义事件」通信

当分配完分数后,将获胜者(Master)的 ID 作为参数,通过自定义事件发送给所有玩家。

if (client.Player.IsMaster) {
// ...
var data = new PlayObject {
{ "winnerId", client.Room.Master.ActorId }
};
var opts = new SendEventOptions {
ReceiverGroup = ReceiverGroup.All
};
client.SendEvent(GAME_OVER_EVENT, data, opts);
}

根据判断胜利者是不是自己,做不同的 UI 显示。

// 注册自定义事件
client.OnCustomEvent += (eventId, eventData, senderId) => {
if (eventId == GAME_OVER_EVENT) {
// 得到胜利者 Id
int winnerId = eventData.GetInt("winnerId");
// 如果胜利者是自己,则显示胜利 UI;否则显示失败 UI
if (client.Player.ActorId == winnerId) {
Debug.Log("win");
resultText.text = "Win";
} else {
Debug.Log("lose");
resultText.text = "Lose";
}
client.Close();
}
};

Demo

我们通过 Unity 完成了这个 Demo,供大家运行参考。

QuickStart 工程