[RemoteConfig] サーバーから値を取得してゲームの挙動を変える
はじめに
今回は、Unity Gaming Servicesの1つである、
RemoteConfigの導入方法や使い方について記事を書いていきます。
お品書き
- Unity RemoteConfig is 何
- プロジェクトの設定
- RemoteConfigを設定してみる
- サーバーから値を取得する
- 環境を切り替える
- Tips
- まとめ
Unity RemoteConfig is 何
Remote Config は、直訳すると遠隔(Remote) の設定(Config)
平たく言うと、ゲーム側で使う値をネットワーク上に設定してゲーム上で使うサービスになります。
類似したサービスにGoogleが提供するFirebase Remote Configというのもあります。
興味がありましたらそちらもチェックしてみてください。
このRemoteConfigを用いると、
公開したアプリやゲームに更新をかけずに挙動を変えることができます。
例えば「ゲームの難易度に関わる値をリアルタイムに変更する」といったことができます。
- 真偽値や数値、文字列などをサーバーに設定
- ゲーム側でサーバーにある設定値を取得
- 取得した値を用いて、ゲーム内の難易度を変更
といった具合です。
これをイチから自前で実装するとなるとサーバーを用意するなど必要になりますが、
RemoteConfigを活用できれば、最低限の知識があれば実現できると思うのでぜひ最後まで読んで頂けると幸いです。
環境
項目 | バージョン |
---|---|
OS | Windows 11 |
Unity | 2021.3.18 |
Remote Config | 3.3.1 |
Authentication | 2.4.0 |
プロジェクトの設定
パッケージをインストール
- Window -> PackageManager を開く。
- ウィンドウ上部で Packages: Unity Registry を選択する。
- Remote Config と Authentication をインストールする。
Unity Servicesのセットアップ
-
Unityエディタ上で、Edit -> ProjectSettings -> Services を開く。
-
Organizationで自身の組織を選ぶ。
-
Create a Unity Project ID - Create Project ID をクリック。
-
一番下の項目は、COPPAに関する質問事項です。
13歳以下にもゲームを配信したい場合はYesに、そうでない場合はNoを選択します。(COPPAについての詳しい話は割愛)
今回はNoを選択します。 -
最後にSave をクリックして保存します。
これでRemoteConfig自体が使えるようになりました。
RemoteConfigを設定してみる
まず、Unityエディタで Window -> Remote Config からウィンドウを開きます。
右上の View in Dashboard をクリックすると、
ブラウザが開き、Web上のダッシュボードが表示されます。
左側のConfigをクリックし設定画面を開きます。
こちらの画面では以下のようなことができます。
- サーバー上の値の追加や変更
- 追加や変更の反映
- 環境を増やす
データの追加
上部の Add Key をクリック
1つ目の欄に呼び出す際のキーとなる文字列を入力
2つ目の欄に取得したいデータの型を以下の中から選択
- Boolean
- Json
- Float
- String
- Integer
- Long
型に応じた値を設定
今回は、 以下のような設定にしました。
設定項目 | 値 |
---|---|
キー名 | integer_value |
タイプ | Integer |
値 | 10 |
Add をクリックして追加
ここで注意なのが、データの追加はされました。
ここから実際に反映させる必要があるので
右上のPublishをクリックし反映確認の画面を表示します。
このウィンドウ右下にPublishボタンがあるので
これをクリックすると実際に取得できる形で公開されるようになります。
Publishをクリックして公開しちゃいましょう。
Add Key ボタン横の日付がUTC時間でPublishを実行した時間になっていればはずです。
日本在住であれば、表示されている日時からマイナス9時間すれば合うはずです。
サーバーからデータを取得してみる
実際にRemoteConfig上のデータを取得するコードを書いていきます。
using System.Threading.Tasks;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.RemoteConfig;
using UnityEngine;
public class RemoteConfigSample : MonoBehaviour
{
public struct UserAttributes {}
public struct AppAttributes {}
async Task Start()
{
// ただしインターネット接続のチェックは行う。
// in order to fail gracefully without throwing exception if connection does not exist
if (Utilities.CheckForInternetConnection())
{
// Unityの認証とコアサービスの初期化
await InitializeRemoteConfigAsync();
}
// 取得が完了した時を検知するためにアクションを登録
RemoteConfigService.Instance.FetchCompleted += ApplyRemoteSettings;
// 取得の実行
RemoteConfigService.Instance.FetchConfigs(new UserAttributes(), new AppAttributes());
}
void ApplyRemoteSettings(ConfigResponse configResponse)
{
Debug.Log("RemoteConfigService.Instance.appConfig fetched: " +
RemoteConfigService.Instance.appConfig.config.ToString());
}
async Task InitializeRemoteConfigAsync()
{
// UnityGameServices用のハンドラを初期化
await UnityServices.InitializeAsync();
// サインインしてない場合
if (!AuthenticationService.Instance.IsSignedIn)
{
// 匿名でサインインする
await AuthenticationService.Instance.SignInAnonymouslyAsync();
}
}
}
上記のスクリプトを作成後、シーン上のGameObjectにアタッチして再生してみます。
Consoleにログが表示され、
先ほどダッシュボードで設定したデータが取得できていることが確認できます。
RemoteConfigService.Instance.appConfig fetched: {
"integer_value": 5
}
データを取り出してみる
先程のサンプルのApplyRemoteSettings
関数内の処理を変えてみます。
public class RemoteConfigSample : MonoBehaviour
{
// ...
void ApplyRemoteSettings(ConfigResponse configResponse)
{
switch (configResponse.requestOrigin)
{
case ConfigOrigin.Default:
var defaultValue = RemoteConfigService.Instance.appConfig.GetInt("integer_value");
Debug.Log($"ロードされず、デフォルト値が使用される。 :{defaultValue}");
break;
case ConfigOrigin.Cached:
var cachedValue = RemoteConfigService.Instance.appConfig.GetInt("integer_value");
Debug.Log($"ロードされず、前回取得した値が使用される。:{cachedValue}");
break;
case ConfigOrigin.Remote:
var remoteValue = RemoteConfigService.Instance.appConfig.GetInt("integer_value");
Debug.Log($"新しい設定が取得され、新しい値が使用される。:{remoteValue}");
break;
}
}
// ...
}
取得元
configResponse.requestOrigin
には、どこからデータを取得したかが入っています。
それをswitch文で分岐しています。
ConfigOrigin | 説明 |
---|---|
Default | 取得できなかった。デフォルトの値を取得する。 |
Cached | 取得できなかった。前回の取得した値を取得する。 |
Remote | 取得できた。最新の値を取得する。 |
値の取得
RemoteConfigから取得した値は、
RemoteConfigService.Instance.appConfig
に用意されているGet系の関数から取得します。
var booleanValue = RemoteConfigService.Instance.appConfig.GetBool("bool_value");
var stringValue = RemoteConfigService.Instance.appConfig.GetString("string_value");
var integerValue = RemoteConfigService.Instance.appConfig.GetInt("integer_value");
var longValue = RemoteConfigService.Instance.appConfig.GetLong("long_value");
var floatValue = RemoteConfigService.Instance.appConfig.GetFloat("float_value");
var jsonValue = RemoteConfigService.Instance.appConfig.GetJson("json_value");
環境を切り替える
アプリやゲームが既にリリースがされている状態で
値の更新をしたりなどを行い、テストしたいケースがあると思います。
そういった場合に、デバッグ用などの他の環境を増やすことができます。
左上にproductionと表示されていると思います。
これは現在の環境名が表示されており、現在production環境ということになります。
(いわゆる本番環境というやつです)
環境の追加
では、新しく環境を追加してみましょう。
productionをクリックし、Manage Environmentをクリックします。
すると環境設定の画面が開くので
右上のAdd environmentから環境を増やすことができます。
Add environmentをクリックします。
すると、ポップアップが表示されるので
環境名を入力してCreateで環境の作成ができます。
環境一覧の三点リーダーのようなアイコンから削除もできます。
環境の切り替え
左上のproductionをクリックすると環境の一覧が表示されます。
development環境をクリックして切り替えてみましょう。
development環境は作ったばかりなので何もない状態です。
取得先の切り替え
development環境は用意できましたが取得先がproductionのままです。
Editorやデバッグ環境では、developmentから値を取得し、
本番環境では、productionから値を取得したいというケースがあると思います。
そういう場合に取得先の環境を切り替えることが可能です。
コード上で取得処理を行う前にRemoteConfigService.Instance.SetEnvironmentID(environmentId)
で取得したい環境IDを設定することでできます。
deveropment環境にproduction環境と同じように、
integer_value
を用意して、production環境とは異なる値を入れてみます。
今回は5にしました。
環境名 | integer_valueの値 |
---|---|
production | 10 |
development | 5 |
切り替えるためには、各環境に振られているEnvironmentIDを知っておく必要があります。
現在表示されている環境名をクリックして、環境を追加する時に使用したManage Environmentsをクリックします。
それぞれ項目をクリックすると
詳細画面が開けるのでそこから各環境のIDをコピーしておきます。
最後に取得先の環境を切り替えるサンプルコードです。
public class RemoteConfigSample : MonoBehaviour
{
[SerializeField]
private bool isDebug;
// TODO: production環境のIDを入れる
private readonly string productionId = "12345678-abcd-abcd-abcd-123456789012";
// TODO: development環境のIDを入れる
private readonly string developmentId = "12345678-abcd-abcd-abcd-123456789012";
async Task Start()
{
// ただしインターネット接続のチェックは行う。
if (Utilities.CheckForInternetConnection())
{
// Unityの認証とコアサービスの初期化
await InitializeRemoteConfigAsync();
}
// 取得先の環境設定を行う
SetEnvironment();
// 取得が完了した時を検知するためにアクションを登録
RemoteConfigService.Instance.FetchCompleted += ApplyRemoteSettings;
// 取得の実行
RemoteConfigService.Instance.FetchConfigs(new UserAttributes(), new AppAttributes());
}
// ...
private void SetEnvironment()
{
if (isDebug)
{
RemoteConfigService.Instance.SetEnvironmentID(developmentId);
}
else
{
RemoteConfigService.Instance.SetEnvironmentID(productionId);
}
}
}
productionId
, developmentId
に
Manage Environmentsで確認したIDを適宜入れてください。
メンバのisDebugをインスペクター上でtrueやfalseにすることで取得先が変わり、値も変わります。
今までの流れに沿って行った場合、
- isDebugにチェックをいれると5
- isDebugのチェックを外すと10
となるはずです。
Tips
Publish後に元に戻す方法
Add keyボタンの横にある、日時が表示されているところをクリックする。
Publishを実行した日時の一覧が表示されるので
戻したいバージョンをクリックするとその時の状態が表示されます。
切り替わった後に、右上の Restore をクリックすると確認のポップアップダイアログが表示されるのでConfirmをクリックし、
Publishすると選択した時点に戻すことができます。
実行せずに確認する方法
RemoteConfigのウィンドウ上の右上にPullというボタンをクリックすることで
サーバーから取得した値が表示されます。
Unityエディタ上からサーバー上のデータを追加や変更をする
RemoteConfigウィンドウ下のAdd Settingからデータの追加が行なえます。
追加ができたら、Pushをクリックして送信します。
無事、データが反映されていました。
まとめ
- RemoteConfigのセットアップ
- サーバーからの値を取得する
- 環境の作成と切り替え
大きく分けてこの3点についてまとめてみました。
今回は書きませんでしたが、環境IDの設定以外にも
ユーザーIDなどのパラメータを設定して取得できる値を変えたりもできるようなので機会があれば記事にしたいと思います。
Unity GamingServicesには、RemoteConfig以外にも「クラウドセーブを可能にするCloudSave」などあるのでぜひ他のサービスも見てみるとよいかも知れません。
また、触る機会があると思うので随時記事にしていきたいです。
Discussion