CC2の楽屋裏

ゲーム制作会社サイバーコネクトツー公式ブログ

*

第006回 コマンドラインからConfig設定を上書きする時の注意点

   

皆さん、こんにちは。サイバーコネクトツーでテクニカルサポートのマネージャーをしています「何でも屋プログラマー」の宇佐見です。
最近は忙しいこともあって記事がなかなか更新できなかったので、今回は小ネタを1つ紹介します。

割と知っている方も多いと思いますが…

UE4は起動時にコマンドラインオプションにて様々な指定が出来ます。その中でも便利なのがコンフィグファイルの設定値を上書きする方法で、以下のような書式で行います。

-ini:inifile:[section1]:parameter1=value1,[section2]:parameter2=value2,...
  • inifile の名前はコンフィグファイルのベース名のみです。 DefaultEngine.ini なら Engine とします
  • section はコンフィグファイル内のセクション名です。 [/Script/Engine.Engine] といった具合です
  • その後に、parameter=value というようにパラメーターを書きます。

1つの”-ini:”指定で、コンフィグファイル1つに対して複数のパラメーター設定が可能です。 UE4はビルドの設定から動作設定まで、様々な設定をConfigファイルに集約しているので、これらを上書きできるのでチョットした設定を変えて動作確認したい場合には非常に便利な機能です。しかし、この指定方法にはちょっとした落とし穴があります。まぁ、個人的にそれでハマったわけですが・・・。なので、まずは簡単に注意点をまとめて書きます。

注意点

  1. Sipping ビルドでは使用できません
  2. 空白(スペース)が使えません
  3. “(ダブルクォーテーション)は使えません
  4. ,(カンマ)が使えません
  5. [ProjectDirectory]/Saved/Config に ini ファイルがあると、そちらが優先されます。
1. Sipping ビルドでは使用できません

ビルド時にこの機能がOFFにされます。条件としては次のように(UE_SERVER || !(UE_BUILD_SHIPPING))定義されていますので、Sippingでもサーバーは指定可能になります。

2. 空白(スペース)が使えません

当たり前のことですが、スペースはコマンドライン解釈時のセパレーターなので使えません。しかし、コマンドラインで空白を使うために引数を””(ダブルクォーテーション)で囲う方法がありますが、それを使用しても空白は使えません。ソースを追ってみるとわかるのですが、UE4のコマンドラインオプションの解釈の最初でスペースが終端として認識されるためです。

3. “(ダブルクォーテーション)は使えません

UE4のパラメーター解釈の最初の段階で削除されます。

4. ,(カンマ)が使えません

コンフィグファイルでは複数の値を持つクラスや構造体に対して値を設定する場合に,(カンマ)が使われるのですが、困ったことにコマンドラインの指定では使えません。つまり、以下の様な指定をする事が出来ません。

SmoothedFrameRateRange=(UpperBound=(Value=80),LowerBound=(Value=40))

コンフィグファイルでは、この様に複数の値を設定する指定は幾つもあるのですが、コマンドラインからは出来ません。
ソースを追跡して分かったのですが、-iniを解釈する際の「一番最初」に,(カンマ)文字でパラメーターを分離します。括弧で括られているかどうかを判定していないので、どうやってもカンマは入れる事が出来ません。

ただ、次の様にカンマを使わなければ、構造体の一部の値を変える事は可能です。

SmoothedFrameRateRange=(UpperBound=(Value=80))

では、面倒ではあるけれど別々の指定にすれば同じ構造体に2つ値が設定できるのでは?と思って試してみましたが、構造体内の複数の値の書き換えは出来ませんでした。以下の2つの方法で試してみましたが適用される値は1つのみでした。
,(カンマ)で区切って複数を指定した場合、前半(UpperBound)のみ設定される。

-ini:Engine:[/Script/UnrealEd.EditorEngine]:SmoothedFrameRateRange=(UpperBound=(Value=80)),[/Script/UnrealEd.EditorEngine]:SmoothedFrameRateRange=(LowerBound=(Value=40))

複数の -iniで指定した場合、後半(LowerBound)のみ設定される。

-ini:Engine:[/Script/UnrealEd.EditorEngine]:SmoothedFrameRateRange=(UpperBound=(Value=80)) -ini:[/Script/UnrealEd.EditorEngine]:SmoothedFrameRateRange=(LowerBound=(Value=40))
5. <[ProjectDirectory]/Saved/Config/に ini ファイルがあると、そちらが優先されます。

これは何度もハマったんですが、UE4ではコンフィグファイルを階層的に管理しており、初期の設定から変更された値のみを [ProjectDirectory]/Saved/Config 以下に書き出します。この設定ファイルが残っていると、こちらが優先されます。その為、コマンドラインオプションで指定しているのに変更されない・・・、といった事が多々おきます。しかもこの設定ファイルは自動的に作られるので、ついつい忘れがちになり、最初は上手く行っていたけど2回目から上手く行かないという事が良く起きました。その為、コマンドラインオプションを指定したバッチファイルを作る際にはこのディレクトリのコンフィグファイルを最初に消すようにしていました。

-ini指定の解釈のプログラム

色々と調べた結果、コマンドラインオプションで行うコンフィグファイルの上書き指定は、本当にちょっとした設定値の変更のみを目的した簡素な実装となっていました。-ini 指定を解釈するプログラムは以下の関数内で処理されますので、スペースやダブルクォーテーションやカンマを上手く解釈するようにしたい場合には、この関数を書き換えるしかありません(あまりお勧めはしませんが)

void FConfigFile::OverrideFromCommandline(FConfigFile* File, const FString& Filename)
{
#if ALLOW_INI_OVERRIDE_FROM_COMMANDLINE
	FString Settings;
	// look for this filename on the commandline in the format:
	//		-ini:IniName:[Section1]:Key1=Value1,[Section2]:Key2=Value2
	// for example:
	//		-ini:Engine:[/Script/Engine.Engine]:bSmoothFrameRate=False,[TextureStreaming]:PoolSize=100
	//			(will update the cache after the final combined engine.ini)
	if (FParse::Value(FCommandLine::Get(), *FString::Printf(TEXT("%s%s"), *CommandlineOverrideSpecifiers::IniSwitchIdentifier, *FPaths::GetBaseFilename(Filename)), Settings, false))
        :

ただし、,(カンマ)を使用できるようにするだけなら、解釈時に使うセパレーターはテーブル化されているので、この部分を書き換えるだけで可能です。実際に”,”→”&”にしたところ、2つの値を設定できるようになりました。

/** A collection of identifiers which will help us parse the commandline opions. */
namespace CommandlineOverrideSpecifiers
{
    // -ini:IniName:[Section1]:Key1=Value1,[Section2]:Key2=Value2
    FString IniSwitchIdentifier     = TEXT("-ini:");
    FString IniNameEndIdentifier    = TEXT(":[");
    FString SectionStartIdentifier  = TEXT("[");
    FString PropertyStartIdentifier = TEXT("]:");
    FString PropertySeperator       = TEXT(",");
}

参考

コンフィギュレーション ファイル | Unreal Engine ドキュメント

終わりに

さて、今回はちょっとした小ネタになってしまいましたが、個人的にハマった際に、公式情報や他の方のブログを見ていてもあまり詳しくは書かれていなかったので、結局はソースファイル内まで追っかけて調べました。同じような所で悩んでいる方がいたら、参考になると幸いです。

皆さんのご意見、ご要望をお待ちしています。下記 CC2技術ブログのメッセージフォームにて、お気軽にお問い合わせください。

「CC2技術ブログ」へのご意見・ご要望はこちらから

 - CC2技術ブログ

  関連記事

第003回 UE4のショートカットキーの仕組み

今回は ツール系テクニカルアーティスト しばはらがお送りします。 突然ですが、P …

第008回:ゲームクリエイターは破壊表現が好き。

皆さんボンジョルノ(イタリアのあいさつ)! 乱読派プログラマ親泊です。 現代ゲー …

tb004_09
第004回 UE4のアセットを一括修正する

ツール系テクニカルアーティストのしばはらです。 プロジェクトが進んで、ある程度ア …

tb004_15
第005回 Tick関数がどう処理されているかUnrealC++を追ってみよう!

皆さんグーテンターク(ドイツのあいさつ)! CC2TechBlog今回の担当は新 …

スクリーンショット (47)
第007回UE4のアセットの参照方法について、そのロードの違い

皆さんボンジュール(フランスのあいさつ)! ランダムのスペルが覚えられないプログ …

第001回 UE4のコンテンツブラウザフィルターを自作する

はじめまして サイバーコネクトツーでツール系テクニカルアーティストをしております …

tb002_04
第002回 アクタのトランスフォームの実態

皆さんストラーズドヴィーチェ(ロシアのあいさつ)! 今回の担当は、新人プログラマ …