ドキュメント

サポート

Cloud Code

他の Unity サービスとのインテグレーション

Connect Cloud Code with other Unity Gaming Services using JavaScript Software Development Kits or REST APIs.
読み終わるまでの所要時間 11 分最終更新 23日前

Cloud Code の潜在能力をフルに利用するには、JavaScript Service SDK または REST API を通じて他の Unity Gaming Services に接続します。 JavaScript SDK はよりシンプルで、より一貫性のある体験を提供します。ただし、使用する UGS サービスに Cloud Code JavaScript SDK がまだない場合は、その REST API を通じて接続できます。

UGS SDK の使用

Cloud Code JavaScript SDK は Cloud Code スクリプトに直接インポートできます。 インテグレーションが利用可能なサービスを確認し、各サービスの詳細な SDK ドキュメントと変更履歴を探すには、Cloud Code Services SDK のドキュメントを参照してください。 Cloud Code JavaScript SDK とそのドキュメントの完全なリストについては、以下の表を参照してください。

サービス

SDK ドキュメント

SDK 変更履歴

Cloud SaveCloud Save SDK[Cloud Save SDK 変更履歴]
EconomyEconomy SDK[Economy SDK 変更履歴]
Remote ConfigRemote Config SDK[Remote Config SDK 変更履歴]
VivoxVivox SDK[Vivox SDK 変更履歴]
LobbyLobby SDK[Lobby SDK 変更履歴]
LeaderboardsLeaderboards SDK[Leaderboards SDK 変更履歴]
MatchmakerMatchmaker SDK[Matchmaker SDK 変更履歴]
MultiplayMultiplay SDK[Multiplay SDK 変更履歴]
FriendsFriends SDK[Friends SDK 変更履歴]
Player NamesPlayer Names SDK[Player Names SDK 変更履歴]
Player AuthenticationPlayer Authentication SDK[Player Authentication 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.4");module.exports = async ({ params, context, logger }) => { const { projectId, playerId, accessToken } = context; const cloudSaveApi = new DataApi(context); try { // Default item data, readable and writable by the player await cloudSaveApi.setItem(projectId, playerId, { key: "defaultData", value: "value" }); // Custom item - non-player entities // Record any game data! const customId = "gameLevelAttributes"; await cloudSaveApi.setCustomItem(projectId, customId, { key: "levelDifficulty", value: "easy" }); // Protected data can be read by player, but not written to await cloudSaveApi.setProtectedItem(projectId, playerId, { key: "protectedItem", value: "verySecretData" }); // Private data that should only be accessed by server/service accounts await cloudSaveApi.setPrivateCustomItem(projectId, customId, { key: "levelTimerInMinutes", value: 25, }); const result = await cloudSaveApi.getItems(projectId, playerId); logger.info(`Retrieved default items from Cloud Save: ${JSON.stringify(result.data)}`) const protectedDataResult = await cloudSaveApi.getProtectedItems(projectId, playerId, ["protectedItem"]); logger.info(`Retrieved protected item from Cloud Save: ${JSON.stringify(protectedDataResult.data)}`) const customDataResult = await cloudSaveApi.getPrivateCustomItems(projectId, customId); logger.info(`Retrieved private custom items from Cloud Save: ${JSON.stringify(customDataResult.data)}`) } catch (err) { logger.error("Error while calling out to Cloud Save", { "error.message": err.message }); throw err; }};

データのクエリ

Cloud Code を使用して、Cloud Save データをクエリできます。 以下のサンプルを使用する前に、Cloud Save サービスクエリを作成 する必要があります。 Unity Cloud Dashboard で Cloud Save サービスに移動し、以下のパラメーターを指定してクエリを作成します。
  • キー
    health
    のデフォルトのアクセスクラスを持つプレイヤーエンティティの昇順クエリ。
  • キー
    difficulty
    のプライベートアクセスクラスを持つカスタムエンティティの降順クエリ。
  • キー
    level
    の保護アクセスクラスを持つプレイヤーエンティティの昇順クエリ。
このサンプルコードは、プレイヤーとカスタムエンティティに対して異なるアクセスモディファイアを使用して Cloud Save データをクエリする方法を示しています。
JavaScript
const _ = require("lodash-4.17");const { DataApi } = require("@unity-services/cloud-save-1.4");module.exports = async ({ params, context, logger }) => { const { projectId, playerId } = context; const cloudSaveApi = new DataApi(context); try { // -------------------------------------------------------------------------------- // Query player data with the key `health` to find players with health lower than 100 // Set data for player const requestData = { data: [{ key: "health", value: 95, }, { key: "stamina", value: 20, } ] }; await cloudSaveApi.setItemBatch(projectId, playerId, requestData); // Query and return player stamina for players with health less than 100 const query = { fields: [{ asc: true, key: 'health', op: 'LT', value: 100, }], returnKeys: ["stamina"] }; const queryRes = await cloudSaveApi.queryDefaultPlayerData(projectId, query); logger.info(`Query results: ${JSON.stringify(queryRes.data)}`) // -------------------------------------------------------------------------------- // Query private custom data to retrieve game levels with easy difficulty // Record two levels with different difficulty levels const casteLevelId = "castleLevel"; const anotherLevelId = "forestLevel"; await cloudSaveApi.setPrivateCustomItem(projectId, casteLevelId, { key: "difficulty", value: "easy" }); await cloudSaveApi.setPrivateCustomItem(projectId, anotherLevelId, { key: "difficulty", value: "hard" }); // Query levels with easy levels only const privateQuery = { fields: [{ asc: false, key: 'difficulty', op: 'EQ', value: 'easy' }], }; const privateQueryRes = await cloudSaveApi.queryPrivateCustomData(projectId, privateQuery); logger.info(`Private query results: ${JSON.stringify(privateQueryRes.data)}`) // -------------------------------------------------------------------------------- // Query protected player data for players that are over level 5 // Set data for player const protectedRequestData = { data: [{ key: "level", value: 15, }, { key: "experiencePoints", value: 20, } ] }; await cloudSaveApi.setProtectedItemBatch(projectId, playerId, protectedRequestData); // Query players over level 5, and return their health const protectedPlayerQuery = { fields: [{ asc: true, key: 'level', op: 'GT', value: 5, }], returnKeys: ["experiencePoints", "level"] }; const protectedPlayerRes = await cloudSaveApi.queryProtectedPlayerData(projectId, protectedPlayerQuery); logger.info(`Protected player query results: ${JSON.stringify(protectedPlayerRes.data)}`) // -------------------------------------------------------------------------------- } catch (err) { logger.error("Error while calling out to Cloud Save", { "error.message": err.message }); throw err; }};

Economy SDK の使用

Economy サービスでは、以下のリソースを使用して、ゲーム内で使用する経済システムを作成、管理、公開できます。
  • Currencies を使用すると、プレイヤーは 1 つ以上の通貨/貨幣単位のゲーム内残高を保持できます。
  • インベントリアイテムは、設定の一部として作成するリソースの定義を表します。プレイヤーは、インベントリアイテムのインスタンス (例えば、同一の剣、盾、帽子の複数のコピー) を所有できます。通貨とは異なり、各インスタンスに独自のプロパティを付与できます。
  • Purchases を使用すると、プレイヤーがゲーム内通貨とインベントリアイテムを買うために、別のゲーム内通貨やインベントリアイテムを使用する (virtual purchases) ことも、デジタルストアフロントで リアルマネー を使用することもできます。
Cloud Code では、通貨やインベントリアイテムを操作でき、スクリプトから直接購入できます。

Economy SDK プレイヤーのインベントリ

以下のスクリプトは、プレイヤーのインベントリに
SWORD
アイテムを追加します。
以下のサンプルを使用する前に、Economy サービス
SWORD
タイプの インベントリアイテムを作成 し、新しい設定を公開 する必要があります。
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
を受け取ります。
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; }}// 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 = {// currencyId: { type: "String", required: true },// };

Economy SDK の仮想購入の使用

以下のスクリプトは、仮想購入を行ってから、プレイヤーのインベントリからアイテムを削除します。 以下のサンプルを使用する前に、Economy サービス仮想購入を作成 し、新しい設定を公開 する必要があります。 スクリプトは
purchaseId
currencyId
をパラメーターとして受け取ります。
currencyId
は、購入を完了するためにプレイヤーが持っている必要のある通貨の ID です。
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; }}// 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 = {// currencyId: { type: "String", required: true },// purchaseId: { type: "String", required: true },// };

Game Overrides での Economy の使用

詳細については、Cloud Code による Economy Game Overrides のドキュメントを参照してください。

Remote Config SDK の使用

Remote Config は、アプリケーションの新しいバージョンをデプロイする必要なしにゲームデザインを調整するために使用できるクラウドサービスです。Remote Config は、名前空間を持つ Key-Value パラメーターのセットで構成され、これらのパラメーターをオーバーライドまたは追加する値のセットを任意で定義できます。 Remote Config 設定は、Cloud Code スクリプトから変更できます。 以下のサンプルは、プレイヤーに 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 を使用すると、プレイヤーはゲームセッションの前または途中に接続できます。プレイヤーは、他のプレイヤーが検索、検出、および参加できる Public ロビーをシンプルなゲーム属性で作成します。招待のみのロビーでは、プレイヤーは選ばれた参加者のみのプライベートスペースを作成することもできます。 以下は、Cloud Code スクリプトを使用してロビーの作成、更新、および heartbeat 送信 を行う方法の例です。 サンプルでは、サービストークンを使用して、所有者のいない空のロビーを作成します。次に、プレイヤーをロビーに追加するために使用できる
playerId
パラメーターと、ロビーを所有するサービスを識別するために使用できる
serviceId
パラメーターを受け取ります。
以下のサンプルは、Private ロビーを作成し、ロビーの名前を更新します。さらに、ロビーに偽装プレイヤーとして参加し、ロビーを取得します。

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; }};// 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 },// playerId: { type: "String", required: true },// };

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; }};// 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 = {// leaderboardId: { type: "String", required: true },// };

Friends SDK の使用

Friends を使用すると、ゲーム内のプレイヤー間の関係を作成および管理できます。Friends を使用して、ゲーム内の関係を管理したり、友達リクエストを送信および承認したり、プレゼンスを制御したり、プレイヤー間でメッセージを送信したりできます。以下のサンプルは、Cloud Code で Friends を使用して、友達リクエストの送信、友達の取得、通知トークンの取得、プレゼンスの設定と受信、メッセージの送信を行う方法を示しています。 Unity Cloud Dashboard でこのサンプルをテストするには、2 つの異なるプレイヤーとして認証された 2 つの異なるブラウザータブでスクリプトを実行します。1 つのタブでは最初のプレイヤーの ID でスクリプトを実行し、別のタブでは 2 番目のプレイヤーの ID でスクリプトを実行します。

JavaScript

const { RelationshipsApi, PresenceApi, MessagingApi, NotificationsApi } = require("@unity-services/friends-1.0");module.exports = async ({ params, context, logger }) => { // Send friend requests and retrieve friends const relationshipsApi = new RelationshipsApi({ accessToken: context.accessToken }); try { const payload = { type: "FRIEND_REQUEST", members: [{ id: params.playerId }] }; const createRes = await relationshipsApi.createRelationship(true, true, payload); logger.info(`New relationship initiated: ${JSON.stringify(createRes.data)}`) } catch (err) { // The call will fail if the friend request has already been sent logger.error("Error while sending a friend request", { "error.message": err.message }); } try { const list = await relationshipsApi.getRelationships(10, 0, true, true, ["FRIEND_REQUEST", "FRIEND"]); logger.info(`Retrieved relationships: ${JSON.stringify(list.data)}`) } catch (err) { logger.error("Error while retrieving relationships", { "error.message": err.message }); } // ------------------------------------------------------------------------- // Retrieve a notification token const notificationsApi = new NotificationsApi({ accessToken: context.accessToken }); try { const auth = await notificationsApi.getNotificationsAuth(); logger.info(`Retrieved notifications subscription token: ${JSON.stringify(auth.data)}`) } catch (err) { logger.error("Error while retrieving notification subscription token", { "error.message": err.message }); } // ------------------------------------------------------------------------- // Set and receive presence const presenceApi = new PresenceApi({ accessToken: context.accessToken }); try { const newStatus = { activity: { // define any payload structure location: "In Menu", }, availability: "ONLINE", }; const setPresenceStatus = await presenceApi.setPresence(newStatus); logger.info(`Changed player presence status for player ${context.playerId}: ${JSON.stringify(setPresenceStatus.data)}`) } catch (err) { logger.error("Error while setting a presence status", { "error.message": err.message }); } try { // This call will fail if the requested user has not accepted the friend request! const presenceStatus = await presenceApi.getPresence(params.playerId); logger.info(`Retrieved player presence for player ${params.playerId}: ${JSON.stringify(presenceStatus.data)}`) } catch (err) { logger.error("Error while retrieving a presence status", { "error.message": err.message }); } // ------------------------------------------------------------------------- // Send messages const messagingApi = new MessagingApi({ accessToken: context.accessToken }); try { const messagePayload = { id: params.playerId, message: { // define any payload structure hello: "world", custom: "sending you a message!" } } // This call will fail if the requested user has not accepted the friend request! const messageResponse = await messagingApi.message(messagePayload); logger.info(`Sent a message to player ${params.playerId}`) } catch (err) { logger.error("Error while sending a message", { "error.message": err.message }); throw err; }}// 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 = {// playerId: { type: "String", required: true },// };

Player Names SDK の使用

Player Names を使用すると、ゲーム内のプレイヤーのプレイヤー名を取得できます。これを使用して、プレイヤーにまだ設定されていない場合に新しいプレイヤー名を生成したり、既存のプレイヤー名を更新したりできます。

JavaScript

const { PlayerNamesApi } = require("@unity-services/player-names-1.0");module.exports = async ({ params, context, logger }) => { const playerNamesApi = new PlayerNamesApi({ accessToken: context.accessToken }); try { const playerData = await playerNamesApi.getName(context.playerId); logger.info(`The received player data is ${JSON.stringify(playerData.data)}`); const updatedData = await playerNamesApi.updateName(context.playerId, {name: "newCustomName"}); logger.info(`The updated player data is ${JSON.stringify(updatedData.data)})`); } catch (err) { logger.error("Error while calling out to Player Names", { "error.message": err.message }); throw err; }};

REST API を通じた UGS との接続

REST API を通じてサービスに接続することもできます。これは、JavaScript SDK がまだないサービスを使用する場合に役立ちます。

認証

ユースケースに応じて、
accessToken
または
serviceToken
を使用して API 呼び出しを認証できます。
serviceToken
を使用して UGS Client API を認証する場合は、呼び出すサービスでサービストークンがサポートされていることを確認します。サービストークンをサポートするサービスとユースケースのリストについては、サービスとアクセストークンのサポート のドキュメントを参照してください。