跳到主要内容

匹配与房间

最后更新:2026 年 9 月 15 日

房间是你游戏的一个实时实例,由游戏服务器托管、以名字标识。在 Unity 客户端里,你有两种方式把玩家送进房间:浏览开放房间列表让玩家挑选,或直接按名字进房。无论哪种,你都会收到一个预订——一张短时票据加上服务器的连接信息——用它来打开你的游戏传输。

本页涵盖什么

这里讲的是 Unity 客户端侧:发现并预订房间。运行托管房间的游戏服务器是另一件事,属于服务器侧。房间不需要自动匹配——浏览和按名字进房本身就能用。自动撮合是单独的一层,放在文末,并且尚未上线。


浏览开放房间​

BrowseRoomsAsync 用已登录玩家的会话读取某个游戏服务器函数的公共房间列表。你会拿到一页房间;玩家从中选一个。

using PlayServ.Sdk.Matchmaking;

var page = await PlayServMatchmaking.BrowseRoomsAsync("arena");

foreach (PlayServRoomListing room in page.Rooms)
{
// room.RoomName, room.Players / room.Capacity, room.State,
// room.Region, room.Connect(host/port/transport)
}

// 分页是显式的——需要才请求下一页:
if (page.HasMore)
page = await PlayServMatchmaking.BrowseRoomsAsync("arena",
new PlayServRoomBrowseQuery { Cursor = page.CursorNext });

PlayServRoomBrowseQuery 可按 PlacementState(例如只看可进入的房间)和 Region 过滤,设置 Limit(默认 50),并携带 Cursor 取下一页。浏览从不撮合或启动任何东西——它是一次读取。


按名字进房​

一旦玩家选好房间——或你的游戏已经知道房间名(私密对局、朋友的房间、你自己服务器列表里的房间)——JoinRoomAsync 会为那个房间请求一个预订。

PlayServMatchResult result = await PlayServMatchmaking.JoinRoomAsync("arena", roomName);

if (result.IsMatched)
{
PlayServMatchReservation r = result.Reservation;
// r.RoomName, r.ReservationToken, r.ExpiresAt
// r.Connect.Host, r.Connect.Port, r.Connect.Transport, r.Connect.ConnectString, r.Connect.Region
}

JoinRoomAsync 只做一件事:请求预订。它不撮合、不启动、不轮询、不重试、不打开传输——从而保持可预测。若在一个预订仍然有效时对同一房间请求两次,你会拿回同一个,而不是重复的。

当进房无法满足时,结果会带上原因——房间不存在(room_not_found)、已满(room_full),或已关闭/正在排空(room_closed)。处理方式是把玩家送回浏览器。


预订​

两条路径都以 PlayServMatchReservation 结束,它就是你抵达房间所需的一切:

字段含义
RoomName该预订允许进入的房间。
ReservationToken一个不透明、一次性、绑定到你会话的令牌。连接时把它出示给游戏服务器。
ExpiresAt预订失效的时间——尽快连接。
Connect服务器在哪:Host、Port、Transport,外加可选的 ConnectString 和 Region。

预订是你进入某个特定房间的许可。它会过期,且一次性,所以拿到后尽快兑换。


一次调用完成进房与连接​

JoinRoomAsync 特意不碰你的网络,因为 PlayServ 并不拥有你的游戏传输(Netcode for GameObjects、Unity Transport、Mirror、裸 socket——由你选)。当你不想手动把两步串起来时,JoinRoomAndConnectAsync 会预订房间,然后把预订交给你提供的连接器(connector),你在那里打开到 Connect 的传输并出示 ReservationToken。

await PlayServMatchmaking.JoinRoomAndConnectAsync(
new PlayServJoinRoomRequest { FunctionSlug = "arena", RoomName = roomName },
connector: async (reservation, ct) =>
{
// 打开你自己的传输到 reservation.Connect,并把令牌交给它
});

连接器必须在 Unity 的主(同步)上下文运行,因为它通常会触及 Unity 网络对象。连接器所需的一切——地址与令牌——都在预订上。

备注

从登录到进入房间的完整路径,以及预订与连接信息如何衔接,见连接到游戏。


与房间里的其他玩家交流​

进入房间与在房间内收发消息是两回事。大厅聊天、准备确认、“谁在这儿”这类信号,用群组:以房间为键订阅一个群组,并向其中所有人发布事件。匹配把玩家送到房间;群组让房间开口说话。


自动匹配​

尚未上线

SDK 也暴露了自动撮合——FindMatchAsync 和 JoinGameAsync,它们替玩家挑房间,而不是让玩家浏览或指名。平台今天没有匹配在线上运行,所以这些方法背后没有东西。请构建在浏览 + 按名字进房(如上)之上,它是完全受支持的。本节仅记录预期形态。

上线后,自动匹配会让玩家请求一场对局并被安置到合适的房间(必要时开一间新房),返回你已经处理过的同一种预订:

// 尚未上线
var result = await PlayServMatchmaking.JoinGameAsync(
new PlayServJoinGameRequest { FunctionSlug = "arena" });
// result.Status: Matched · Bot · NotFound → result.Reservation 同上

由于结果是同一种预订类型,已经在浏览与按名字进房的代码,等撮合上线后只需很小改动就能沿用。


下一步​

  • 连接到游戏——完整的 Unity 路径:登录 → 预订 → 连接 → 游戏
  • 群组——房间内聊天、在场信号与广播
  • 游戏服务器托管——托管你所浏览并连接的房间的服务器