文档

支持

Cloud Code

使用 Lobby

Use Cloud Code and Lobby service together to trigger server-side actions when players join lobbies.
阅读时间3 分钟最后更新于 1 个月前

您可以将 Lobby 与 Cloud Code 结合使用来定义游戏中的常见触发器。假设游戏大厅已准备好开始匹配。您可以触发以下脚本来响应游戏大厅准备就绪状态。此示例还与 Remote Config 集成。 在按照此示例操作之前,请通过 Unity Cloud Dashboard 启用 Lobby 和 Cloud Code,然后按照步骤安装所需的 SDK。使用服务身份验证在项目中创建一个大厅,并记下其 ID。您可以通过 Cloud Code 执行此操作(查看 Unity Lobby 的示例)。 以下示例为脚本提供了两个参数:用于创建大厅的服务 ID 以及大厅 ID。我们获取大厅后,通过对大厅元数据进行一些更改来更新大厅。这些更改如下:
  • 锁定大厅,使新玩家无法再加入大厅。
  • 使用大厅的玩家 ID 为游戏构建随机的“玩家顺序”。
  • 使用 Remote Config 中定义的
    LOBBY_CURRENT_MAPS
    配置来随机选择一张游戏地图。该脚本返回一个指示成功或失败结果的基本布尔值。
JavaScript
const _ = require("lodash-4.17");const { LobbyApi, DataObjectVisibilityEnum } = require("@unity-services/lobby-1.2");const { SettingsApi } = require("@unity-services/remote-config-1.1");module.exports = async ({params,context,logger}) => { const { serviceId, lobbyId } = params; const { projectId, environmentId, playerId } = context; const lobbyApi = new LobbyApi(context); const remoteConfig = new SettingsApi(context); try { const {data: lobby} = await lobbyApi.getLobby(lobbyId, serviceId); return setUpGame(remoteConfig, projectId, environmentId, serviceId, lobbyApi, logger, lobby); } catch (err) { logger.error(`Failed to set up lobby: ${err.response.data.detail}`); return false; }};// Updates a lobby to set up for the start of a game, including reading a value from Remote Config to randomly assign to the lobby.async function setUpGame(remoteConfig, projectId, environmentId, serviceId, lobbyApi, logger, lobby) { let playerIds = []; for (let i = 0; i < lobby.players.length; i++) { playerIds.push(lobby.players[i].id); } // Generate a turn order for the game by shuffling the player IDs. _.shuffle(playerIds); // Load all of the maps that are currently configured as available in Remote Config and pick a random one for this game. let maps = getCurrentMapsFromRemoteConfig(remoteConfig, projectId, environmentId) if (maps == null) { throw "Maps loaded from Remote Config are null."; } let gameMap = _.sample(maps); try { const updateResponse = await lobbyApi.updateLobby( lobby.id, serviceId, null, { isLocked: true, // Lock the lobby so that new players cannot join. hostId: playerIds[0], // Transfer host ownership from the service to one of the players. data: { "playerOrder": { value: playerIds.toString(), visibility: DataObjectVisibilityEnum.Member // Set the visibility of the player order so that only lobby members can access it. }, "map": { value: gameMap, visibility: DataObjectVisibilityEnum.Public // Set the visibility of the game map so that anyone who views the lobby can access it. } } } ); return true; } catch (err) { throw err; } return lobbyUpdateSuccess;}// Loads the Remote Config JSON value for LOBBY_CURRENT_MAPS and returns the array of maps inside of it.// If the JSON is invalid, the return value is null.async function getCurrentMapsFromRemoteConfig(remoteConfig, projectId, environmentId) { const currentMapsId = 'LOBBY_CURRENT_MAPS'; const remoteConfigResponse = await remoteConfig.assignSettingsGet( projectId, environmentId, 'settings', [currentMapsId] ); let mapsJSON = remoteConfigResponse?.data?.configs?.settings?.[currentMapsId]; if (!mapsJSON || !mapsJSON.maps || mapsJSON.maps.length == 0) { return null; } return mapsJSON.maps;}// Uncomment the code below to enable the inline parameter definition// - Requires Cloud Code JS dev environment setup with NodeJS (https://docs.unity3d.com/Packages/com.unity.services.cloudcode@latest/index.html?subfolder=/manual/Authoring/javascript_project.html)//// module.exports.params = {// serviceId: { type: "String", required: true },// lobbyId: { type: "String", required: true },// };
此处的 Remote Config JSON 结构简单,但您可以扩展此示例配置来实现对游戏的更精细控制。同样,除了游戏设置之外,您可能还需要考虑大量不同的 Cloud Code 触发器,例如:
  • 在创建大厅时触发调整元数据值并清理字符串。
  • 使用 Cloud Save 玩家数据过滤玩家的查询结果、批准/拒绝玩家加入大厅以及设置元数据。
  • 使用 Economy 数据设置玩家或大厅元数据。