# コードの統合

> Implement Remote Config in your game code using the RemoteConfig API.

`RemoteConfig` API は、`Unity.Services` 名前空間に含まれています。この名前空間をゲームスクリプトに含める必要があります。この名前空間のクラスとメソッドの詳細については、[Remote Config スクリプティング API](https://docs.unity3d.com/Packages/com.unity.remote-config@latest) および [Remote Config Runtime スクリプティング API](https://docs.unity3d.com/Packages/com.unity.remote-config-runtime@latest/index.html?subfolder=/api/index.html) のドキュメントを参照してください。

## カスタム属性の実装##implementing-custom-attributes

[Game Overrides の条件](./game-overrides-and-settings.md#condition) にカスタム属性を提供するには、以下の `struct` 変数をゲームスクリプトに実装します。

* アプリケーションが独自のトラッキング方法を使用している場合、`Delivery` 構造体を使用し、`SetCustomUserID` メソッドでカスタムプレイヤー ID 属性を提供します。開発者が定義した属性がない場合、Remote Config は ID を自動生成します。
* `userAttributes` 構造体を使用して、カスタム **user** カテゴリ属性を提供します。
* `appAttributes` 構造体を使用して、カスタム **app** カテゴリ属性を提供します。
* `filterAttributes` 構造体を使用して、ペイロードを削減するために、カスタム **filter** カテゴリ属性を提供します。

**ノート**: カスタム属性は完全に任意です。これらの構造体がなくても、Unity Remote Config を実装し、事前定義された Unity 属性を Game Overrides の条件に使用できます。属性カテゴリの詳細については、[条件](./game-overrides-and-settings.md#condition) についてのドキュメントを参照してください。

初めに、カスタム属性を実装し、関数の概要を示すスクリプトのフレームワークを作成します。

```c#
using UnityEngine;
using Unity.Services.RemoteConfig;
using Unity.Services.Authentication;
using Unity.Services.Core;
using System.Threading.Tasks;

public class RemoteConfigExample : MonoBehaviour {

    public struct userAttributes {
      // Optionally declare variables for any custom user attributes:
        public bool expansionFlag;
    }

    public struct appAttributes {
      // Optionally declare variables for any custom app attributes:
        public int level;
        public int score;
        public string appVersion;
    }

    public struct filterAttributes {
      // Optionally declare variables for attributes to filter on any of following parameters:
        public string[] key;
        public string[] type;
        public string[] schemaId;
    }

    // Optionally declare a unique assignmentId if you need it for tracking:
    public string assignmentId;

    // Declare any Settings variables you’ll want to configure remotely:
    public int enemyVolume;
    public float enemyHealth;
    public float enemyDamage;


    // The Remote Config package depends on Unity's authentication and core services.
    // These dependencies require a small amount of user code for proper configuration.
    async Task InitializeRemoteConfigAsync()
    {
            // initialize handlers for unity game services
            await UnityServices.InitializeAsync();

            // options can be passed in the initializer, e.g if you want to set AnalyticsUserId or an EnvironmentName use the lines from below:
            // var options = new InitializationOptions()
            // .SetEnvironmentName("testing")
            // .SetAnalyticsUserId("test-user-id-12345");
            // await UnityServices.InitializeAsync(options);

            // remote config requires authentication for managing environment information
            if (!AuthenticationService.Instance.IsSignedIn)
            {
                await AuthenticationService.Instance.SignInAnonymouslyAsync();
            }
    }

    async Task Awake () {
        // In this example, you will fetch configuration settings on Awake.
    }

    // Create a function to set your variables to their keyed values:
    void ApplyRemoteConfig (ConfigResponse configResponse) {
        // You will implement this in the final step.
    }
}
```

## ランタイムでの設定の取得と適用##fetching-and-applying-settings-at-runtime

次に、Remote Config サポート関数を実装し、ランタイムに呼び出してサービスから Key-Value ペアを取得し、それらを適切な変数にマップします。

Remote Config サービスは、ランタイムでの設定の取得と適用を処理するための [`RemoteConfigService.Instance`](https://docs.unity3d.com/Packages/com.unity.remote-config-runtime@latest/index.html?subfolder=/api/Unity.Service.RemoteConfig.RemoteConfigService.html) オブジェクトを返します。この例では、このオブジェクトを使用してリモートサービスから Key-Value ペアを取得し、取得時に `ApplyRemoteConfig` 関数を呼び出します。`ApplyRemoteConfig` は、取得リクエストへの応答を表す [`ConfigResponse`](https://docs.unity3d.com/Packages/com.unity.remote-config-runtime@latest/index.html?subfolder=/api/Unity.Service.RemoteConfig.ConfigResponse.html) 構造体を受け取り、[`RemoteConfigService.Instance.appConfig`](https://docs.unity3d.com/Packages/com.unity.remote-config-runtime@latest/index.html?subfolder=/api/Unity.Service.RemoteConfig.RemoteConfigService.appConfig.html) メソッドを使用して設定を適用します。

```c#
    // Retrieve and apply the current key-value pairs from the service on Awake:
    async Task Awake () {

        // initialize Unity's authentication and core services, however check for internet connection
        // in order to fail gracefully without throwing exception if connection does not exist
        if (Utilities.CheckForInternetConnection()) 
        {
            await InitializeRemoteConfigAsync();
        }

        // Add a listener to apply settings when successfully retrieved:
        RemoteConfigService.Instance.FetchCompleted += ApplyRemoteConfig;

        // you can set the user’s unique ID:
        // RemoteConfigService.Instance.SetCustomUserID("some-user-id");

        // you can set the environment ID:
        // RemoteConfigService.Instance.SetEnvironmentID("an-env-id");

        // Fetch configuration settings from the remote service, they must be called with the attributes structs (empty or with custom attributes) to initiate the WebRequest.
        await RemoteConfigService.Instance.FetchConfigsAsync(new userAttributes(), new appAttributes());

        // Example on how to fetch configuration settings using filter attributes:
        // var fAttributes = new filterAttributes();
        // fAttributes.key = new string[] { "sword","cannon" };
        // RemoteConfigService.Instance.FetchConfigs(new userAttributes(), new appAttributes(), fAttributes);

        // Example on how to fetch configuration settings if you have dedicated configType:
        // var configType = "specialConfigType";
        // Fetch configs of that configType
        // RemoteConfigService.Instance.FetchConfigs(configType, new userAttributes(), new appAttributes());
        // Configuration can be fetched with both configType and fAttributes passed
        // RemoteConfigService.Instance.FetchConfigs(configType, new userAttributes(), new appAttributes(), fAttributes);

        // All examples from above will also work asynchronously, returning Task<RuntimeConfig>
        // await RemoteConfigService.Instance.FetchConfigsAsync(new userAttributes(), new appAttributes());
        // await RemoteConfigService.Instance.FetchConfigsAsync(new userAttributes(), new appAttributes(), fAttributes);
        // await RemoteConfigService.Instance.FetchConfigsAsync(configType, new userAttributes(), new appAttributes());
        // await RemoteConfigService.Instance.FetchConfigsAsync(configType, new userAttributes(), new appAttributes(), fAttributes);

    }

    void ApplyRemoteConfig (ConfigResponse configResponse) {
        // Conditionally update settings, depending on the response's origin:
        switch (configResponse.requestOrigin) {
            case ConfigOrigin.Default:
                Debug.Log ("No settings loaded this session and no local cache file exists; using default values.");
                break;
            case ConfigOrigin.Cached:
                Debug.Log ("No settings loaded this session; using cached values from a previous session.");
                break;
            case ConfigOrigin.Remote:
                Debug.Log ("New settings loaded this session; update values accordingly.");
                break;
        }

        enemyVolume = RemoteConfigService.Instance.appConfig.GetInt("enemyVolume");
        enemyHealth = RemoteConfigService.Instance.appConfig.GetInt("enemyHealth");
        enemyDamage = RemoteConfigService.Instance.appConfig.GetFloat("enemyDamage");
        assignmentId = RemoteConfigService.Instance.appConfig.assignmentId;

        // These calls could also be used with the 2nd optional arg to provide a default value, e.g:
        // enemyVolume = RemoteConfigService.Instance.appConfig.GetInt("enemyVolume", 100);
    }
```

## 特定の設定タイプを使用した設定へのアクセス##accessing-configs-with-particular-config-types

対応する設定タイプのすべての設定は、キャッシュに正しく格納されます。これには、以下のように設定タイプを渡すことでアクセスできます。

```c#
RemoteConfigService.Instance.GetConfig("settings");
RemoteConfigService.Instance.GetConfig("specialConfigType");
```

## メタデータパラメーター##metadata-parameters

リクエスト時に毎回バックエンドで割り当てイベントが作成されます。

そのリクエストへの応答内で、`configs` ブロックとともに、応答の一部として以下のパラメーターから成る `metadata` ブロックが返されます。


**Frame:**
![MetaDataBlock](/api/media?file=/remote-config/media/images/meta-data-block.png)

* 各割り当てイベントで `assignmentId` が作成され、イベントと最終的なユーザーのセグメント化を追跡するために使用されます。
* `environmentId` は割り当てが行われた環境を表します。
* `configAssignmentHash` は割り当て時に作成され、その特定の割り当ての一意のシグネチャを表します。

`configAssignmentHash` は以下のように `appConfig` からアクセスできます。

```c#
RemoteConfigService.Instance.appConfig.configAssignmentHash
```

使用したい `configAssignmentHash` がわかったら、以下のように `SetConfigAssignmentHash()` メソッドを使用してペイロード内でバックエンドに渡すことができます。

```c#
RemoteConfigService.Instance.SetConfigAssignmentHash("4d1064c5198a26f073fe8301da3fc5ead35d20d1"); 
```

`configAssignmentHash` をバックエンドに渡すと、バックエンドはその特定の `configAssignmentHash` の作成時に存在する設定を返します。

`configAssignmentHash` の生存期間の TTL は 56 時間です。その期間を過ぎても `configAssignmentHash` を再びリクエストできますが、TTL が 56 にリセットされます。

## その他の考慮事項##working-with-templates

### オブジェクトを上書きするために JSON 型の設定を使用する##utilizing-setting-of-type-json-for-overwriting-objects

例えば、以下のようにコードに `CubeInfo` クラスがあるとします。

```c#
[System.Serializable]
public class CubeInfo
{
    public float rotateX = 10f;
    public float rotateY = 10f;
    public float rotateZ = 10f;
    public float rotSpeed = 1.0f;
    public Color color = Color.white;
}

```

JSON エディターモーダルは、以下のタイプの JSON 変換をサポートしています。

* テキストアセット
* スクリプタブルオブジェクト
* ゲームオブジェクトにアタッチされているカスタムスクリプト

テキストアセットを使用する場合、以下のように `CubeInfo` クラスと構造的に一致する Settings をセットアップします。


**Frame:**
![CubeJsonTextAsset](/api/media?file=/remote-config/media/images/cube-json-text-asset.png)

スクリプタブルオブジェクトの場合、以下のように、選択ボックスの横にある右上の点をクリックし、スクリプタブルオブジェクトを選択すると、自動的に JSON に変換されます。


**Frame:**
![CubeJsonSO](/api/media?file=/remote-config/media/images/cube-json-so.png)

シーンからゲームオブジェクトを選択すると、そのゲームオブジェクトにアタッチされているすべての MonoBehaviour カスタムスクリプトに追加のドロップダウンが表示されます。いずれかを選択すると、JSON に変換されます。


**Frame:**
![CubeJsonCustomScript](/api/media?file=/remote-config/media/images/cube-json-custom-script.png)

これらの設定をランタイムに CubeInfo オブジェクトに適用するには、該当する [JsonUtility](https://docs.unity3d.com/ScriptReference/JsonUtility.html) クラスを使用します。

```c#
case ConfigOrigin.Remote:
    var jsonCubeString = RemoteConfigService.Instance.appConfig.GetJson("jsonCubeString");
    JsonUtility.FromJsonOverwrite(jsonCubeString, CubeInfo);
```

### セキュリティ##security

Unity が Remote Config データをダウンロードするウェブサービスは読み取り専用ですが、安全ではありません。第三者が Remote Config データを参照する可能性があります。設定に機密情報や秘密情報を保存しないようにしてください。同様に、保存された設定ファイルはエンドユーザーに読み取りおよび変更される可能性があります (ただし、Remote Config は使用可能なインターネット接続で次にセッションが開始されたときに変更をすべて上書きします)。

### プラットフォームサポート##platform-support

Remote Config Runtime の最新バージョンは、以下のプラットフォームでテストされています。

デスクトップ:

* Windows (PC)
* Mac
* Linux スタンドアロン

モバイル:

* iOS
* Android

Remote Config のコンソールサポートについては、Unity の [サポートチーム](https://support.unity.com/hc/en-us/requests/new?ticket_form_id=360001936712) にお問い合わせください。
