与其他 Unity 服务集成
要充分发挥 Cloud Code 的潜力,可以通过 JavaScript Service SDK 或 REST API 将其与其他 Unity Gaming Services(Unity 游戏服务)连接起来。
JavaScript SDK 更简单,并提供更一致的体验。但是,如果要使用的 UGS 服务还没有 Cloud Code JavaScript SDK,仍可以通过其 REST API 与其连接。
使用 UGS SDK
您可以将 Cloud Code JavaScript SDK 直接导入到 Cloud Code 脚本中。
要查看可用的服务集成,并查找每个服务的详细 SDK 文档和变更日志,请参阅 Cloud Code Services SDK 文档。
注意:其他 Unity 服务的方法的返回对象包含有关请求的其他信息,例如请求的标头或响应。要访问响应的有效负载,请引用对象的 data
属性。
如需查看 Cloud Code JavaScript SDK 及其文档的完整列表,请参阅下表:
服务 | SDK 文档 | SDK 变更日志 |
---|---|---|
[Cloud Save] | [Cloud Save SDK] | [Cloud Save SDK 变更日志] |
[Economy] | [Economy SDK] | [Economy SDK 变更日志] |
[Remote Config] | [Remote Config SDK] | [Remote Config SDK 变更日志] |
[Vivox] | [Vivox SDK] | [Vivox SDK 变更日志] |
[Lobby] | [Lobby SDK] | [Lobby SDK 变更日志] |
[Leaderboards] | [Leaderboards SDK] | [Leaderboards SDK 变更日志] |
Cloud Code 脚本允许您通过组合不同的 UGS 服务来处理跨玩家数据。如需了解更多信息,请参阅关于如何处理跨玩家数据的文档。
使用 Cloud Save SDK
您可以使用 Cloud Save 服务将长期的玩家数据(如游戏进度)从游戏保存到云中,并可以随时随地跨设备访问玩家数据。这意味着,当玩家更换设备或重新安装游戏时,Cloud Save 可用于减少数据丢失。
您可以使用 Cloud Code 将数据保存到 Cloud Save 以及从中读取数据。以下示例代码演示了如何访问和修改玩家的 Cloud Save 数据:
JavaScript
const _ = require("lodash-4.17");
const { DataApi } = require("@unity-services/cloud-save-1.3");
module.exports = async ({ params, context, logger }) => {
const { projectId, playerId, accessToken } = context;
const cloudSaveApi = new DataApi({accessToken});
try {
await cloudSaveApi.setItem(projectId, playerId, {
key: "test",
value: "value"
});
result = await cloudSaveApi.getItems(projectId, playerId);
return result.data;
} catch (err) {
logger.error("Error while calling out to Cloud Save", {"error.message": err.message});
throw err;
}
};
使用 Economy SDK
Economy 服务允许您使用以下资源在游戏中创建、管理和发布 Economy 系统:
- 货币:允许玩家在游戏中拥有一种或多种货币/面额的余额。
- 背包物品:表示在配置过程中创建的资源的定义。玩家可以拥有背包物品的实例(例如,相同的剑、盾牌、帽子的多个副本),与货币不同,您还可以为每个实例指定各自的属性。
- 购买:允许玩家使用其他游戏内货币和背包物品来购买游戏内货币和背包物品(虚拟购买),或通过数字店面用真实资金进行购买。
借助 Cloud Code,可以直接通过脚本处理货币、背包物品和购买。
Economy SDK 玩家背包
以下脚本将 SWORD
物品添加到玩家的背包中。
在使用以下示例之前,您需要在 Economy 服务中创建类型为 SWORD
的背包物品,并发布您的新配置。
**注意:**如果您发布了背包配置,但未找到背包物品,可能需要刷新 playerId
。或者,请更新脚本以使用配置分配哈希。
JavaScript
const { InventoryApi } = require("@unity-services/economy-2.4");
module.exports = async ({ params, context, logger }) => {
const { projectId, playerId, accessToken } = context;
const inventory = new InventoryApi({ accessToken });
const addInventoryRequest = { inventoryItemId : "SWORD" };
try {
await inventory.addInventoryItem({
addInventoryRequest,
playerId,
projectId
});
const result = await inventory.getPlayerInventory({ projectId, playerId });
return result.data;
} catch (err) {
logger.error("Error while retrieving inventory items", {"error.message": err.message});
throw err;
}
}
Economy SDK 玩家货币
以下脚本将设置玩家的货币余额,然后增加和减少余额。
在使用以下示例之前,您需要在 Economy 服务中拥有已发布的货币。
以下脚本使用了必需的字符串参数 currencyId
。
**注意:**如果您发布了货币配置,但未找到货币,可能需要刷新 playerId
。或者,请更新脚本以使用配置分配哈希。
JavaScript
const { CurrenciesApi } = require("@unity-services/economy-2.4");
module.exports = async ({ params, context, logger }) => {
const { projectId, playerId, accessToken } = context;
const { currencyId } = params;
const currencies = new CurrenciesApi({ accessToken });
try {
await currencies.setPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyBalanceRequest: { balance: 100 } });
await currencies.decrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 50 } });
await currencies.incrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 10 } });
const result = await currencies.getPlayerCurrencies({ projectId, playerId });
return result.data;
} catch (err) {
logger.error("Error while updating currencies", {"error.message": err.message}, {"currencyId" : currencyId});
throw err;
}
}
使用 Economy SDK 虚拟购买
以下脚本将进行虚拟购买,然后从玩家的背包中删除物品。
在使用以下示例之前,您需要在 Economy 服务中创建虚拟购买,并发布您的新配置。
此脚本接受 purchaseId
和 currencyId
作为参数。currencyId
是玩家完成购买所需的货币 ID。
**注意:**如果您发布了虚拟购买配置,但未找到购买,可能需要刷新 playerId
。或者,请更新脚本以使用配置分配哈希。
JavaScript
const { CurrenciesApi, PurchasesApi, InventoryApi } = require("@unity-services/economy-2.4");
module.exports = async ({ params, context, logger }) => {
const { projectId, playerId, accessToken } = context;
const { purchaseId, currencyId } = params;
const inventory = new InventoryApi({ accessToken });
const purchases = new PurchasesApi({ accessToken });
const currencies = new CurrenciesApi({ accessToken });
try {
// Give a player some currency to complete the purchase
await currencies.setPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyBalanceRequest: { balance: 1 } });
const makeVirtualPurchaseResult = await purchases.makeVirtualPurchase({ projectId, playerId, playerPurchaseVirtualRequest: { id: purchaseId } });
const getPlayerInventoryResult = await inventory.getPlayerInventory({ projectId, playerId });
await inventory.deleteInventoryItem({ projectId, playerId, playersInventoryItemId: makeVirtualPurchaseResult.data.rewards.inventory[0].playersInventoryItemIds[0], inventoryDeleteRequest: {} });
return {
makeVirtualPurchaseResult: makeVirtualPurchaseResult.data,
getPlayerInventoryResult: getPlayerInventoryResult.data
};
} catch (err) {
logger.error("Error while calling out to Economy", {"error.message": err.message});
throw err;
}
}
Economy 与 Game Overrides 结合使用:
如需了解更多信息,请参阅 Economy Game Overrides 与 Cloud Code 文档。
使用 Remote Config SDK
Remote Config 属于一种云服务;借助此服务,无需部署应用程序新版本,即可调整游戏设计。Remote Config 由一组命名空间的键/值参数组成,您可以选择定义一组覆盖或添加到这些参数的值。
您可以通过 Cloud Code 脚本修改 Remote Config 设置。
以下示例演示了如何为玩家分配 Remote Config 设置。
JavaScript
const { SettingsApi } = require("@unity-services/remote-config-1.1");
module.exports = async ({ context, logger }) => {
const { projectId, playerId, accessToken } = context;
const remoteConfig = new SettingsApi({ accessToken });
try {
const result = await remoteConfig.assignSettings({ projectId, "userId": playerId, "attributes": { "unity": {}, "app": {}, "user": {} } });
return result.data;
} catch (err) {
logger.error("Error while assigning settings", {"error.message": err.message});
throw err;
}
}
使用 Vivox SDK
Vivox 为游戏提供基于语音和文本的通信服务。Cloud Code 允许您生成 Vivox 令牌,让游戏客户端可以安全地访问 Vivox 服务操作。
以下示例演示了如何使用 Cloud Code 脚本生成 Vivox 令牌。
JavaScript
const { TokenApi } = require("@unity-services/vivox-0.1");
module.exports = (async e => {
const o = {
iss: "gary.charlton.oogabooga",
exp: 1559359105,
vxa: "join",
vxi: 1,
f: "sip:.username.@domain.vivox.com",
t: "sip:confctl-g-channelname@domain.vivox.com"
};
try {
return TokenApi.generateVivoxToken("TEST_KEY", o)
} catch (err) {
logger.error("Error while generating vivox token", {"error.message": err.message});
throw err;
}
});
使用 Lobby SDK
Lobby 允许玩家在游戏会话之前或期间进行连接。玩家使用简单的游戏属性创建公共大厅,然后其他玩家可以搜索、发现和加入大厅。“仅限受邀者加入”的大厅还允许玩家仅为选定的参与者创建私有空间。
以下示例说明了如何使用 Cloud Code 脚本创建和更新大厅以及对大厅进行心跳检测。
此示例使用服务令牌创建一个没有所有者的空大厅。然后,接受一个可用于将玩家添加到大厅的 playerId
参数,以及一个可用于标识拥有大厅的服务的 serviceId
参数。
虽然您可以使用 Cloud Code 以玩家身份发出 Lobby 请求,但默认使用服务身份验证。您可以在所需的任何值下方给出此示例使用的 serviceId
;这样会为 Lobby 服务提供一个唯一标识符,以便区分您的服务拥有的大厅。
以下示例将创建一个私有大厅,更新大厅的名称,以模拟玩家的身份加入大厅,以及获取大厅。
JavaScript
const { LobbyApi } = require("@unity-services/lobby-1.2");
module.exports = async ({ params, context, logger }) => {
const lobbyApi = new LobbyApi(context);
const { serviceId, playerId } = params;
try {
// Create a private lobby without any initial players.
const { data: lobby } = await lobbyApi.createLobby(
serviceId,
null, {
name: "my new lobby name",
maxPlayers: 4,
isPrivate: true,
}
);
logger.info(`Created lobby: ${JSON.stringify(lobby)}`);
// Heartbeat the lobby to keep it active.
await lobbyApi.heartbeat(lobby.id, serviceId);
// Update the lobby's name and get the updated lobby.
const { data: updateResponse } = await lobbyApi.updateLobby(
lobby.id,
serviceId,
null, { name: "my updated lobby name" }
);
logger.info(`Lobby updated: ${JSON.stringify(updateResponse)}`);
// Join the lobby as an impersonated player.
const { data: joinResponse } = await lobbyApi.joinLobbyById(lobby.id, serviceId, playerId);
logger.info(`Player joined: ${JSON.stringify(joinResponse)}`);
// Get and return the lobby.
const getResponse = await lobbyApi.getLobby(lobby.id, serviceId);
return getResponse.data;
} catch (err) {
logger.error("Error while calling out to Lobby", {"error.message": err.message});
throw err;
}
};
使用 Leaderboards SDK
Leaderboards 允许您为游戏创建和管理排行榜。
在使用以下示例之前,您需要在 Leaderboards 服务中创建排行榜。
以下示例展示了如何向排行榜添加分数,以及使用 Cloud Code 脚本获取排行榜分数。此脚本使用了 leaderboardId
参数。
JavaScript
const { LeaderboardsApi } = require("@unity-services/leaderboards-1.1");
module.exports = async ({ params, context, logger }) => {
const leaderboardsApi = new LeaderboardsApi({accessToken : context.accessToken});
let result;
try {
await leaderboardsApi.addLeaderboardPlayerScore(context.projectId, params.leaderboardId, context.playerId, { score : 20});
const result = await leaderboardsApi.getLeaderboardScores(context.projectId, params.leaderboardId);
return result.data;
} catch (err) {
logger.error("Error while calling out to Leaderboards", {"error.message": err.message});
throw err;
}
};
通过 REST API 与 UGS 进行连接
您还可以通过服务的 REST API 与服务进行连接。如果要使用一个尚无 JavaScript SDK 的服务,这将非常有用。
身份验证
根据您的用例,您可以使用 accessToken
或 serviceToken
对 API 调用进行身份验证。如果使用 serviceToken
对 UGS Client API 进行身份验证,请确保要调用的服务支持服务令牌。如需查看支持服务令牌的服务和用例的列表,请参阅服务令牌和访问令牌支持文档。
**注意:**如果要调用的服务提供了 Cloud Code JavaScript SDK,则可以改用该 SDK,这样就不必直接调用服务 API。如需了解更多信息,请参阅 Cloud Code Services SDK。