#memo

indiedev太郎

Configurationファイル何処に何があってどれをどうしているのか問題

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

Configurationファイル、各地に散らばっており、何がどうなっているのかさっぱりわからない
まず、コンフィギュレーションがなんでこんなたくさん分かれてるかというと、デフォルトに段階がある

1. UE4ビルド時のデフォルト設定 = base
2.プロジェクトのデフォルト設定 = default
3.ユーザーのデフォルト設定 = local

1から順にファイルを見ていって、ある変数についての言及があるたびに追加・削除、みたいなことをしていて、これで後半の階層にある設定が優先されるようになっている

で、Shippingバージョンと普通のバージョンではこの階層の位置が違っている

Base Configuration
普段のだと"C:\Program Files (x86)\Epic Games\4.12\Engine\Config"とかにある
Shippingバージョンでは"Engine\Config"に入っている

Default Configuration
普段のだと"マイドキュメント\Unreal Projects\プロジェクト\Config"
Shippingだと"プロジェクト\Config" にある

Local Configuration
普段のだと"マイドキュメント\Unreal Projects\プロジェクト\Saved\Config\Windows"
Shippingは"C:\Users\なまえ\AppData\Local\プロジェクト名\Saved\Config\WindowsNoEditor"


ここで、ConfigがC++でどう実装されて読み込まれてるのかも確認する

Configファイルの値を必要とするメンバがあるクラスは、UCLASSマクロの引数にそう定義する必要がある
たとえばGameUserSettingsは

UCLASS(config=GameUserSettings, configdonotcheckdefaults)
class ENGINE_API UGameUserSettings : public UObject

で、InputSettingsは

UCLASS(config=Input, defaultconfig)
class ENGINE_API UInputSettings : public UObject

こんな感じ

ふたつ目の引数に違いがあって、defaultconfigとconfigdonotcheckdefaultsがある
この指定子をソースで確認すると

//Class containing config properties. Usage config=ConfigName or config=inherit (inherits config name from base class).
config,
//Handle object configuration on a per-object basis, rather than per-class. 
perObjectConfig,
//Determine whether on serialize to configs a check should be done on the base/defaults ini's
configdonotcheckdefaults,
//Save object config only to Default INIs, never to local INIs.
defaultconfig,

とのことです。
なのでInputSettingsクラスはローカルのInput.iniファイルに記載しても読み込んでくれない
perObjectConfigについては公式のページに書いてある

メンバ変数での取得方法も、Config指定子が必要

UPROPERTY(config, EditAnywhere, Category="MouseProperties", AdvancedDisplay)
uint32 bEnableFOVScaling:1;

こうなってるメンバ変数は、インスタンスが作成された時に自動的にConfigファイルから値をとってきてくれる(はず)(あとで確認する)
この時に見にいくConfigファイルをUCLASSで指定してある


例えばゲーム内設定で、キーバインドやグラフィック設定があるけど、この設定はどこにあるとそれっぽいかといわれるとLocalであってほしくて、ここのファイルを全削除するとプロジェクトデフォルトの設定に戻るとかだとうれしい
ただInputSettingsとかは、localの物を拾ってくれないので、ここを自分で書き加える必要があることがわかる、あるいはエンジンを改造する



InputSettingsは少し置いておくとして、プロジェクト開始時の解像度設定に焦点をあてて、その記載が何処にあるのか、設定で変更する場合どうしたら良いのかを確認していく

まず、UE4エディターで実行した時の解像度は、今回はあんまり関係なくて、これはエディタの設定から見れるし、Shippingバージョンではここの設定は見ない

https://i.gyazo.com/fe8286b6d1af3a1e4e90fd773377a4ec.png

というか解像度設定、パッケージングしないとini反映されないので、そっちの話になる

解像度設定が書いてあるGameUserSettings.iniは、baseとdefaultを見に行かないことを確認したので、localを見に行くと、GameUserSettings.iniが存在している
ただ、この中身は何も記載されてなくて、何らかの方法で解像度設定がされていることになる
ソースを本当に流し読みすると、ここになにもないとWindowedフルスクリーン(1)、ディスプレイ解像度で起動するようになっている(ような気がする)

GameUserSettings.iniになんか書いて起動すれば起動モードとサイズは変わるはずで、これがなんかのエッセンスになります

[/Script/Engine.GameUserSettings]
ResolutionSizeX=1000
ResolutionSizeY=600
FullscreenMode=2
Version=5

Version必要で、Version未指定だったり、5以外の数字があると弾かれてイニシャライズされない

これでゲーム内からコンフィグファイルを書き換える

if (!GConfig) return;

GConfig->SetInt(
	TEXT("hoge"),
	TEXT("waa"),
	100,
	GGameUserSettingsIni
);
GConfig->Flush(false, GGameUserSettingsIni);

こんな関数実行すれば、localにあるiniが更新されるようになるので、ロジック組めば終わりかとおもいきや、iniのカテゴリの中でもGameUserSettingsだけはしっかりクラスが用意されていて、ココらへんの解像度更新ロジックがもうすべて揃っています・・・・

Game User Settings - Epic Wiki

このSaveSettings()を使用するとConfigファイルがLocalに生成されたり更新されたりするので、これを使用したほうが完全に良い
しかもGameUserSettingsはデフォルトでBPで扱えるっぽくて、これはもう別記事にまとめました

miyahuji111.hatenablog.com

掘ったビデオ設定周りが妙に充実していて本題からちょっとずれてしまったけれど、通常のConfigurationファイルを扱おうと思ったらC++は必要っぽい