大厅查询
玩家可以使用查询 API 来发现他们可能想要加入的公开大厅。玩家可以浏览大厅并查看其公开信息。每个大厅都有自己的元数据,其中包括大厅名称、项目 ID、最大玩家数量以及玩家列表。游戏开发者还可以添加自定义元数据,以添加该游戏独有的特定类型数据,例如地图 ID。尚未加入大厅的玩家只能看到可见性设为公开的自定义数据。
大厅排序
玩家可以指定查询 API 返回大厅查询结果时的排序方式。例如,如果玩家只想查看最近创建的大厅,那么他们可以按照大厅创建时间进行排序。
大厅过滤
玩家可以在使用查询 API 时指定一个或多个过滤条件,从而仅查看符合其所设参数的大厅。例如,玩家可以按大厅名称、最大大厅大小、可用玩家空位和创建日期进行过滤,也可以使用游戏类型、地图或等级要求等自定义数据来进行过滤。您可以仅在自己的项目和环境中进行过滤。
以下代码示例展示了如何对大厅进行过滤:
C#
try
{
QueryLobbiesOptions options = new QueryLobbiesOptions();
options.Count = 25;
// Filter for open lobbies only
options.Filters = new List<QueryFilter>()
{
new QueryFilter(
field: QueryFilter.FieldOptions.AvailableSlots,
op: QueryFilter.OpOptions.GT,
value: "0")
};
// Order by newest lobbies first
options.Order = new List<QueryOrder>()
{
new QueryOrder(
asc: false,
field: QueryOrder.FieldOptions.Created)
};
QueryResponse lobbies = await Lobbies.Instance.QueryLobbiesAsync(options);
//...
}
catch (LobbyServiceException e)
{
Debug.Log(e);
}
使用自定义数据进行过滤
大厅具有五个自定义字符串字段 (S1-S5) 和五个自定义数值字段 (N1-N5),供您在查询中使用。这对于为玩家自定义大厅浏览体验非常有用。例如,游戏可以让玩家根据模式、地图、地区和技能进行过滤。
以下代码示例展示了如何使用自定义数据进行过滤:
C#
// Creating a custom indexed string property to be used as lobby data
var lobbyData = new Dictionary<string, DataObject>
{
{
"GameMode", new DataObject(
visibility: DataObject.VisibilityOptions.Public,
value: "Conquest",
index: DataObject.IndexOptions.S1)
}
};
// ... set the lobby data ...
// Create query filter for the custom data that was set above
var queryFilter = new List<QueryFilter>()
{
new QueryFilter(
field: QueryFilter.FieldOptions.S1,
op: QueryFilter.OpOptions.EQ,
value: "Conquest")
};
随机生成的查询结果
当多名玩家同时使用相同的过滤条件来查询大厅,并且返回的结果超过所请求的数量时,Lobby 服务会使用随机抽样来返回不同的查询结果。这有助于减少争用,确保将玩家均匀分配到不同的大厅,以尽早开始游戏。这减少了加载时间,有助于在多个玩家寻找相似游戏时加快连接开始游戏的过程。
随机抽样确保使用相同搜索条件的玩家不会看到相同的查询结果,从而避免他们尝试加入自查询后已满员的大厅。然而,竞争总有可能会发生,即玩家可能尝试加入已满员的大厅;客户端逻辑应该预期这种情况,并应就此合理规划,以便妥善处理大厅加入失败的情况。
分页
客户端也可以选择不随机生成查询结果,这时可以进行结果分页。在查询返回非随机化结果时,响应中会返回一个继续令牌。这个令牌可以提供给后续的查询,以获取下一页的结果。请注意,即使下一页没有大厅,仍然会提供一个继续令牌。
以下代码示例展示了使用继续令牌的基本模式:
C#
// Common query options to use for paging
var queryOptions = new QueryLobbiesOptions
{
SampleResults = false, // Paging cannot use randomized results
Filters = new List<QueryFilter>
{
// Only include open lobbies in the pages
new QueryFilter(
field: QueryFilter.FieldOptions.AvailableSlots,
op: QueryFilter.OpOptions.GT,
value: "0")
},
Order = new List<QueryOrder>
{
// Show the oldest lobbies first
new QueryOrder(true, QueryOrder.FieldOptions.Created),
}
};
var response = await LobbyService.Instance.QueryLobbiesAsync(queryOptions);
var lobbies = response.Results;
// A continuation token will still be returned when the next page is empty,
// so continue paging until there are no new lobbies in the response
while (lobbies.Count > 0)
{
// Do something here with the lobbies in the current page
// Get the next page. Be careful not to modify the filter or order in the
// query options, as this will return an error
queryOptions.ContinuationToken = response.ContinuationToken;
response = await LobbyService.Instance.QueryLobbiesAsync(queryOptions);
lobbies = response.Results;
}