モジュール構造
Understand the structure of a Cloud Code module project and how it exposes endpoints.
読み終わるまでの所要時間 6 分最終更新 23日前
Cloud Code モジュールは、ゲームクライアントが呼び出すことのできるエンドポイントを公開する単純な .NET プロジェクトです。モジュールは、同様のパラダイムを .NET クラスライブラリとして採用します。例えば、標準の C# クラスは以下のようになる場合があります。
コンパイルされると、クラスnamespace ModulesExample;public class Example{ private static string[] GetCheatCodes() { return new string[] { "LEAVEMEALONE", "ASPIRINE", "BIGBANG" }; } public void ChangeHaircut(string haircutName) { }}
ExampleChangeHaircut()これにより、開発者はアクセスモディファイアを通じてライブラリのインターフェースを選択できます。Cloud Code モジュールは同じ方法で動作しますが、代わりにusing ModulesExample;class UsageExample{ public void GameLoop() { Example.ChangeHaircut("buzzcut"); // Compile error "Cannot access private method 'GetCheatCodes()' here" var cheatCodes = Example.GetCheatCodes(); }}
[CloudCodeFunction("ChangeHaircut")]C# プロジェクト
Cloud Code モジュールプロジェクトは、クラスライブラリ C# プロジェクトです。プロジェクトは、ソリューションの一部にすることもできます。最も単純なプロジェクト構造は以下のようになります。または、ソリューション内の場合は、以下のようになります。├─ Main.csproj└─ Dependencies└─ HelloWorld.cs
ソリューションには、相互に参照する複数のプロジェクトを入れることもできます。これにより、テストプロジェクトを簡単に追加でき、コードの再利用が可能になります。以下の例は、有効なプロジェクト構造を示します。Sample.sln├─ Main.csproj └─ Dependencies └─ HelloWorld.cs
ただし、Cloud Code 関数を入れることができるのはメインプロジェクトだけです。 Cloud Code モジュールの単体テストの記述方法については、単体テストの作成 を参照してください。 適用されるストレージ制限を確認するには、Cloud Code 制限 を参照してください。Sample.sln├─ Main.csproj └─ Dependencies └─ HelloWorld.cs├─ Tests.csproj └─ Dependencies └─ Tests.cs├─ Other.csproj └─ Dependencies └─ Class1.cs
メインプロジェクト
ソリューションには複数の C# プロジェクトを追加できますが、メインプロジェクトはモジュールごとに 1 つだけです。メインプロジェクトには、すべてのモジュールエントリーポイント (CloudCodeFunction
メインプロジェクトは、Cloud Code サービスにデプロイするプロジェクトでもあります。メインプロジェクトで参照されていないプロジェクトと依存関係は Cloud Code サービスにデプロイしません。
メインプロジェクトの名前は、Cloud Code サービスにデプロイするアーカイブの名前と一致する必要があります。
サンプルプロジェクト
最も単純なモジュールプロジェクトは、以下の構造を持ちます。以下のサンプルは、文字列Sample.sln├─ Main.csproj └─ Dependencies └─ HelloWorld.cs
Hello World!Hellousing Unity.Services.CloudCode.Core;namespace Sample;public class HelloWorld{ [CloudCodeFunction("Hello")] public string PrintHello() { return "Hello World!"; }}
Cloud Code NuGet パッケージ
.NET プロジェクトとして、Cloud Code モジュールプロジェクトはパッケージ化されたコードを共有するために NuGet も使用します。 NuGet の詳細については、Microsoft のドキュメント を参照してください。 Cloud Code は、モジュールに追加できる 2 つのパッケージを提供します。- : このパッケージには、
com.Unity.Services.CloudCode.Core属性など、Cloud Code のコア機能が含まれています。すべての Cloud Code モジュールに、このパッケージが必要です。CloudCodeFunction - : これは、Cloud Code サービスを操作するために使用できる Unity Gaming Services API を含む任意のパッケージです。このパッケージを使用して、Cloud Save などの他の Cloud Code SDK を呼び出すことができます。
com.Unity.Services.CloudCode.Apis
コード構造
コード構造の問題を回避するには、以下のガイドラインに従います。CloudCodeFunction 属性
メソッドを Cloud Code 関数としてマークし、実行可能な Cloud Code モジュールエンドポイントにするには、CloudCodeFunctionメソッドシグネチャ
モジュール関数のメソッドシグネチャには以下の構造体を使用します。[CloudCodeFunction("FunctionName")]public async Task<ReturnType> FunctionName(IGameApiClient gameApiClient, IExecutionContext ctx, string parameter1, string parameter2){ ...}
モジュールでのシングルトンパターンの使用
シングルトンパターンを使用して、Cloud Code C# パッケージと外部サービス呼び出しを統合できます。シングルトンパターンは、Cloud Code のパフォーマンスとスケーラビリティを改善し、同じオブジェクトの複数のインスタンスを作成しないようにします。 依存性注入 を使用して、モジュールにIGameApiClientIPushClientパラメーターを渡す
モジュール関数にパラメーターを渡すことができます。プリミティブな型と複雑な型
これには、すべてのプリミティブな型 (intstringboolfloatList<T>Dictionary<T>Dictionary<string, T>stringList<string>同じパラメーターを使用してモジュール関数を定義します。{ "params": { "parameter1": "a", "parameter2": ["b", "c"] }}
[CloudCodeFunction("SimpleParams")]public async Task SimpleParams(IExecutionContext ctx, string parameter1, List<string> parameter2){ return parameter1 + parameter2[0] + parameter2[1];}
カスタム型
モジュールプロジェクトで定義したカスタム型を渡すこともできます。 例えば、JSON オブジェクトをモジュールオブジェクトに渡すことができます。モジュールプロジェクトに{ "params": { "player": { "name": "player", "health": 50, "stamina": 20, "inventory": { "count": 5, "weight": 20 } } }}
PlayerInventorypublic class Player{ public string Name { get; set; } public int Health { get; set; } public int Stamina { get; set; } public Inventory Inventory { get; set; }}public class Inventory{ public int Count { get; set; } public int Weight { get; set; }}[CloudCodeFunction("CustomParams")]public async Task<string> CustomParams(IExecutionContext ctx, Player player){ return $"{player.Name} has {player.Health} health and {player.Stamina} stamina and {player.Inventory.Count} items in their inventory with a total weight of {player.Inventory.Weight}";}
使用可能なインターフェース
Cloud Code モジュールは、IGameApiClientIAdminApiClientIPushClientIExecutionContextICloudCodeSetupIGameApiClient インターフェース
IGameApiClientIGameApiClient- インターフェースを実装するクラスを定義し、
ICloudCodeSetupをシングルトンとして追加します。GameApiClientpublic class ModuleConfig : ICloudCodeSetup{ public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); }} - インターフェースを関数パラメーターとしてモジュール関数に渡します。
IGameApiClient
IAdminApiClient インターフェース
IAdminApiClientIAdminApiClient- インターフェースを実装するクラスを定義し、
ICloudCodeSetupをシングルトンとして追加します。AdminApiClientpublic class ModuleConfig : ICloudCodeSetup{ public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(AdminApiClient.Create()); }} - インターフェースを関数パラメーターとしてモジュール関数に渡します。
IAdminApiClient
IPushClient インターフェース
IPushClientIPushClient- インターフェースを実装するクラスを定義し、
ICloudCodeSetupをシングルトンとして追加します。PushClientpublic class ModuleConfig : ICloudCodeSetup{ public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(PushClient.Create()); }} - オブジェクトを関数パラメーターとしてモジュール関数に渡します。
PushClient
IExecution コンテキスト
モジュール内の他の UGS サービスを呼び出すには、IExecutionContext- : 呼び出し元が認証されたプロジェクト ID。
ProjectId - : スクリプトを実行したプレイヤー ID。ノート: サービスがスクリプトを呼び出す場合、プレイヤー ID は使用できません。
PlayerId - : モジュールの環境 ID。
EnvironmentId - : モジュールの環境名。
EnvironmentName - : プレイヤーが Cloud Code を認証するために使用した JSON Web Token (JWT) 認証情報。
AccessToken - : サービスアカウントのユーザー ID。(ノート: サービスがスクリプトを呼び出す場合、ユーザー ID は使用できません。)
UserId - : 発行者またはサービスアカウントトークン。(ノート: プレイヤーがスクリプトを呼び出す場合、発行者は使用できません。) 例えば、Multiplay が呼び出す場合、発行者は
Issuerです。multiplay - : Cloud Code サービスアカウント JWT 認証情報。
ServiceToken - : プレイヤーの Analytics ユーザー ID。(ノート: サービスがスクリプトを呼び出す場合、分析ユーザー ID は使用できません。)
AnalyticsUserId - : プレイヤーの Unity デバイスインストール ID。(ノート: サービスがスクリプトを呼び出す場合、Unity インストール ID は使用できません。)
UnityInstallationId
CloudCodeFunctionusing Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;namespace Sample;public class HelloWorld{ private static ILogger<HelloWorld> _logger; public CloudSaveSdkSample(ILogger<HelloWorld> logger) { _logger = logger; } [CloudCodeFunction("GetData")] public async Task<object> GetData(IExecutionContext context, IGameApiClient gameApiClient, string key) { try { var result = await gameApiClient.CloudSaveData.GetItemsAsync(context, context.AccessToken, context.ProjectId, context.PlayerId, new List<string> { key }); return result.Data.Results.First().Value; } catch (ApiException ex) { _logger.LogError("Failed to get data from Cloud Save. Error: {Error}", ex.Message); throw new Exception($"Failed to get data for playerId {ctx.PlayerId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}
トークン認証
AccessTokenServiceTokenIExecutionContextトークンタイプ | 発生元 | データアクセス | 使用方法 |
|---|---|---|---|
| Authentication サービス によって生成されます。 | 認証されたプレイヤーのみ。 | |
| Cloud Code によって生成されます。 | クロスプレイヤーデータアクセス。 | |
AccessTokenAccessTokenすべてのプレイヤーのデータにアクセスするには、using Microsoft.Extensions.DependencyInjection;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;using Unity.Services.CloudSave.Model;namespace TokenSample;public class TokenSample{ [CloudCodeFunction("GetKeysForAuthenticatedPlayer")] public Task<ApiResponse<GetKeysResponse>> GetPlayerKeys(IExecutionContext ctx, IGameApiClient gameApiClient) { try { // Using ctx.AccessToken to access the data for the player calling the function return gameApiClient.CloudSaveData.GetKeysAsync(ctx, ctx.AccessToken, ctx.ProjectId, ctx.PlayerId); } catch (ApiException e) { throw new Exception($"Failed to get keys for playerId {ctx.PlayerId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}
ServiceTokenplayerId2 つのトークンの違いの詳細な説明は、サービスとアクセストークン のドキュメントを参照してください。using Microsoft.Extensions.DependencyInjection;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;using Unity.Services.CloudSave.Model;namespace TokenSample;public class TokenSample{ [CloudCodeFunction("GetKeysForAnyPlayer")] public Task<ApiResponse<GetKeysResponse>> GetPlayerKeys(IExecutionContext ctx, IGameApiClient gameApiClient, string playerId) { try { // Using ctx.ServiceToken to access the data for any player return gameApiClient.CloudSaveData.GetKeysAsync(ctx, ctx.ServiceToken, ctx.ProjectId, playerId); } catch (ApiException e) { throw new Exception($"Failed to get keys for playerId {ctx.PlayerId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}
Cloud Code モジュールメタデータ
Cloud Code モジュールとそのメタデータを取得するには、Cloud Code サービスにGET{ "name": "string", "language": "CS", "tags": { "property1": "string", "property2": "string" }, "signedDownloadURL": "string", "dateCreated": "2022-04-05T09:12:13Z", "dateModified": "2022-04-05T09:12:13Z"}