(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]

サーバーサイド不要&無料でゲーム内のデータをリモートで変更出来るUnity公式の機能 Remote Config 【Unity】【Unity Services】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 2018.4.6f1


はじめに

以前、ブラウザ上で設定したデータを、プログラムで簡単に取得出来る

Remote SettingsというUnityサービスの機能を紹介したのですが、

f:id:kan_kikuchi:20190827062021g:plain


その際に同系統のRemote Configという機能(やっぱり無料!)を教えてもらったので、

今回はそれを試してみた感じの記事です!



イメージとしては以下のような感じで、Remote Settingsと同じような事が出来ます

Remote Settingsと違い、ブラウザでの操作が必要なく、Unityエディタ上で完結するみたいでした。

f:id:kan_kikuchi:20190908045625g:plain


なお、Unity Remote Configを使えるのは、Unity2018.3以降です。

また、プレビュー版なので、今後大きな変更が加わる可能性がある点には注意が必要です。


導入

それでは早速、Remote Configの導入方法の解説です。

まず、Remote Configの導入にはPackage Managerを使います。



Window/Package Managerからウィンドウを開き、

f:id:kan_kikuchi:20190904091359j:plain


AdvancedのShow preview packagesを有効にします。

f:id:kan_kikuchi:20190904091448j:plain


そして、Remote Configを検索し、Installボタンを押します。

f:id:kan_kikuchi:20190904091457j:plain


ちなみにドキュメントは同ページのView documentationから開けます。

f:id:kan_kikuchi:20190904093710j:plain


インストールが完了したら、Player Settingsを開き、

Scripting Runtime Versionを.NET 4.X Equivalent以上にします。

f:id:kan_kikuchi:20190904094017j:plain
f:id:kan_kikuchi:20190904094011j:plain
f:id:kan_kikuchi:20190904094022j:plain


さらに、Unityエディタの右上にある雲のボタンを押し、

f:id:kan_kikuchi:20190824055336j:plain


Unity Servicesのウィンドウで、organizationを選択し、

Createボタン押して、Unity Services上にProject IDを作成し、導入完了です。

f:id:kan_kikuchi:20190824055556j:plain



データの設定

導入を完了すると、Window/Remote Config/Remote Config Management

Remote Configのデータ設定や確認が出来るウィンドウが開けるようになります。

f:id:kan_kikuchi:20190904094357j:plain
f:id:kan_kikuchi:20190904094401j:plain


Add Settingボタンを押すとデータが追加でき、

Pushで設定したデータの送信Pullでリモート上のデータの取得が出来ます。

f:id:kan_kikuchi:20190907045555j:plain


ちなみに設定できるデータの型はfloat, int, long, bool, stringです。

f:id:kan_kikuchi:20190907045603j:plain


なお、データはDevelopmentとReleaseに分けて設定が出来ますが、

f:id:kan_kikuchi:20190904094251j:plain


エディタ上やDevelopment Buildが有効な時はDevelopmentのデータを使い、

それ以外の場合の時はReleaseのデータを使う、

という感じで自動で読み込み先が変わるようになっています。

f:id:kan_kikuchi:20190827050003j:plain



プログラムでデータを使う

設定したデータをプログラムで読み込んで使う場合は以下のような感じになります。

using UnityEngine;
using Unity.RemoteConfig; //ConfigManagerなどRemoteConfig系のモノを使うのに必要

/// <summary>
/// RemoteConfigの動作確認用クラス
/// </summary>
public class RemoteConfigSample : MonoBehaviour {
  
  //ユーザーの属性用の構造体
  private struct UserAttributes {}

  //アプリの属性用の構造体
  private struct AppAttributes {}

  //=================================================================================
  //初期化
  //=================================================================================
  
  private void Awake () {
    //データのロードが完了した時のイベントに処理を登録
    ConfigManager.FetchCompleted += ApplyRemoteSettings;

    //ユーザIDを設定
    ConfigManager.SetCustomUserID("some-user-id");

    //データのロードを開始
    ConfigManager.FetchConfigs<UserAttributes, AppAttributes>(new UserAttributes(), new AppAttributes());
    
    //試しにAwakeでデータをロードしてみる(まだロードが完了されていないので、前に読み込んだ値が表示される)
    Debug.Log("Awake : " + ConfigManager.appConfig.GetInt ("IntKey1"));
  }

  //=================================================================================
  //更新
  //=================================================================================
  
  //データのロードの更新が完了し、反映された
  private void ApplyRemoteSettings (ConfigResponse configResponse) {
    switch (configResponse.requestOrigin) {
      case ConfigOrigin.Default:
        Debug.Log ("キャッシュがない時?デフォルトの値を設定?");
        break;
      case ConfigOrigin.Cached:
        Debug.Log ("キャッシュされたデータのロードが完了?");
        
        //データをロード、前に読み込んだ値が表示
        Debug.Log("Cached : " + ConfigManager.appConfig.GetInt ("IntKey1"));
        break;
      case ConfigOrigin.Remote:
        Debug.Log ("リモートのデータのロードが完了");
        
        //データをロード、リモートからロードした最新の値が表示
        Debug.Log("Remote : " + ConfigManager.appConfig.GetInt ("IntKey1"));
        break;
    }
  }

}
f:id:kan_kikuchi:20190908045625g:plain


コードをざっくり説明していくと、

まず、ConfigManager.appConfigのGet系メソッド(GetIntとか)を使ってデータを取得します。

//試しにAwakeでデータをロードしてみる(まだロードが完了されていないので、前に読み込んだ値が表示される)
Debug.Log("Awake : " + ConfigManager.appConfig.GetInt ("IntKey1"));


ただし、データを取得する前に

リモートのデータを確認するConfigManager.FetchConfigsの実行が最低一回は必要です。

(この前にデータを取得しようとするとエラーが出る)


また、一度リモートから取得した値はキャッシュされるので、

リモートの値を常に反映したい場合は、データの取得の前に毎回実行する必要があります。

//データのロードを開始
ConfigManager.FetchConfigs<UserAttributes, AppAttributes>(new UserAttributes(), new AppAttributes());


ConfigManager.FetchConfigsでUserAttributesとAppAttributesという2つの構造体を渡していますが、

これはそれぞれユーザーとアプリの属性を設定するためのもので、

例えば「アプリのバージョンごとにリモートから取得する値を変える」

といったように、属性に合わせて取得する値を変える時に使います


ただし、「リモートから取得する値はみんな同じ」場合は

特に属性が必要ないので、例のように空の構造体でOKです。

//ユーザーの属性用の構造体
private struct UserAttributes {}

//アプリの属性用の構造体
private struct AppAttributes {}


ConfigManager.FetchConfigsは実行して、すぐにリモートの値を取得できるわけではないので、

ConfigManager.FetchCompletedに処理を登録する事で、値の取得の完了を検知出来るようにします。


FetchCompletedに登録した処理にはconfigResponseが渡されるので、

そのrequestOriginを見て、どのタイミングかを判断します。

//データのロードが完了した時のイベントに処理を登録
ConfigManager.FetchCompleted += ApplyRemoteSettings;
//データのロードの更新が完了し、反映された
private void ApplyRemoteSettings (ConfigResponse configResponse) {
  switch (configResponse.requestOrigin) {
    case ConfigOrigin.Default:
      Debug.Log ("キャッシュがない時?デフォルトの値を設定?");
      break;
    case ConfigOrigin.Cached:
      Debug.Log ("キャッシュされたデータのロードが完了?");
      
      //データをロード、前に読み込んだ値が表示
      Debug.Log("Cached : " + ConfigManager.appConfig.GetInt ("IntKey1"));
      break;
    case ConfigOrigin.Remote:
      Debug.Log ("リモートのデータのロードが完了");
      
      //データをロード、リモートからロードした最新の値が表示
      Debug.Log("Remote : " + ConfigManager.appConfig.GetInt ("IntKey1"));
      break;
  }
}


Remote ConfigではユーザIDを設定して、ユーザを識別することも可能ですが、例のように

全員同じID(ユーザを識別しない)にしても、そもそも設定しなくても問題はないようです。

//ユーザIDを設定
ConfigManager.SetCustomUserID("some-user-id");


おわりに

今回は説明を省きましたが、データにルールを設定して、

ユーザやアプリの属性ごとに読み込む値を変えることも可能です。



ちなみに同様の事がRemote Settingsでも出来るみたいなので、基本的な機能の差は少ないようです。