【UE5】 UE5 Localizationがパッケージで動作しなかった問題

結論から書くと
Internationalization SupportがEnglishになっていたのが問題でした。

UEで多言語化を実装していたときに遭遇した問題の解決方法のメモ

症状

多言語化対応は英語、日本語、中国語(簡体字)、中国語(繁体字)
EditorのStandAloneでは正常に表示、言語の切り替えができていたのに
パッケージングすると英語 <-> 日本語のみしか正常に動作しなくなっていた。

対応.1

ProjectSettings -> Packaging ->Licalizations to Package
で必要な言語を選択

対応.2

ProjectSettings -> Packaging -> Internationalization Support
に適切なものを設定
どれが適切かは、対応する言語によって異なるので
こちらを確認して対応する必要があります。

その他の多言語化周りの細かい設定部分についてこちらの公式ページにまとまっているので
ここを読むのが正しい情報を得られると思います。

【UE5】 UE5 プロジェクト用のGameUserSettingsを用意する

UEにはUGameUserSettingsというものがありそちらには設定に関するものが数値が入っています。

steam対応のゲームで
Saveデータはクラウドで共有したいけど、設定はパソコン毎に持ちたい
という場合や、
設定を変えたらゲームが動かなくなった際に削除して初期値に戻す
という場合に使い分けるということですね。

UGameUserSettingsの公式のドキュメントはこちら
ここにある数値で足りない場合にはプロジェクトごとに用意する必要があります。

そこでハマったポイントをメモしておきます。

1. UGameUserSettingsを継承したクラスを作成

UCLASS()
class GAME_API UMYGameUserSettings : public UGameUserSettings
{
};

2. ProjectSettingから作成したSettingクラスを指定

Engine -> GeneralSettingsのなかにGameUserSettingsClassの項目があるので
そこに1で作成したクラスを指定します。

これで作成したクラスがUEの関数でGetできます。

3.任意のプロパティを追加

UCLASS()
class GAME_API UMYGameUserSettings : public UGameUserSettings
{
    GENERATED_BODY()
public:
    UPROPERTY(Config) float BGMVolume;
    UPROPERTY(Config) float SEVolume;
};

任意のプロパティを追加します。
(上記コードにはないですがコンストラクタで初期化してください)

ここでUPROPERTY(Config)
をつけないと保存されないので注意が必要です。

これで保存ができていると
GameUserSettings.ini
に追加したプロパティが保存されているのがわかると思います
(GameUserSettings.iniは実行環境によって参照するものが異なります)

当然ですがGameUserSettings.iniは暗号化されていないので
ユーザーにみられても良いものだけを保存しましょう

【UE5】 UE5 DataTableの行のみをEditorで指定して取り出す

2025/2/10追記

DataTableの指定の行を取り出したいときに

通常
DataTatbleを指定 -> RowNameを検索 -> 要素を取り出す
という流れになりますが
その際の設定ミスを減らしたいと思い調べたものをまとめました。

DataTableをフィルタリング

EditorでDataTableを指定する際に以下のように書くとプロジェクト内すべてのDataTableが候補に出てきます。

UPROPERTY(EditDefaultsOnly)
UDataTable* PlayerStatusDataTable;

指定の行のみを取り出すには
Unreal側に用意されているFDataTableRowHandleを使用すると以下のようになります。

UPROPERTY(EditDefaultsOnly, meta = (RowType ="/Script/TESTProject.MyDataTable"))
FDataTableRowHandle PlayerStatusData;


あとは以下のように書くと指定のRowの要素を取得することができます。

		if(PlayerStatusData.IsNull())
		{
			UE_LOG(LogTemp, Warning, TEXT("DataTableRowHandle is valid"));
			return;
		}
		FMyDataTable* MyDataTable = PlayerStatusData.GetRow<FMyDataTable>(FString("ContextText"));
		UE_LOG(LogTemp, Warning, TEXT("Name: %s"), *MyDataTable->Name);

これでデータを作成してもらう人に設定する際に
Rowの名前を文字列で指定する事がなくなるのでデータの設定ミスなどが防げるかと思います。

余談ですが
以下のような記述でDataTableを指定する部分のフィルタリングができないかと思いましたが
動作しないようでした.
DataTableはRowTypeを指定しているので記述方法はあっていると思うのですがなにか別の書き方があるのか…

UPROPERTY(EditDefaultsOnly, meta = (RowType = "/Script/TESTProject.MyDataTable"))
UDataTable* EnemyAsset;

追記

以下のように記述することでDataTableを選択する項目のフィルタリングが可能でした。

UPROPERTY(EditDefaultsOnly, meta = (RequiredAssetDataTags = "RowStructure=/Script/YOUR_PROJECT.DataTableStructName"))
UDataTable* HogeDataTable= nullptr;

こちらの記事に詳しくまとめました。
【UE5】 DataTableの選択肢をフィルタリングする

【UE5】RetainerBox->GetEffectMaterial()がnullになる問題

RetainerBox->GetEffectMaterial()でDynamicInstanceMaterialを取得して
マテリアルのパラメータを変更しようとしたときに遭遇した問題メモ

問題

WidgetをAddToviewportしたときにRetainerBoxのマテリアルの画像を差し替えたりする
初期化処理を実装していると
RetainerBox->GetEffectMaterial()
の返り値がnullptrになってしまう事があった。

解決策

呼び出しのタイミングの問題
具体的には
NativeOnInitializedで呼び出すとnullを返して
NativeConstructだと正常に動作する。


NativeConstructはAddtoViewPortされる度に呼ばれるので注意が必要
NativeConstructでフラグを使って一度のみ初期化する
のような対応が必要になってしまう
NativeOnInitializedは一度のみしか呼ばれないのでそちらのほうがキレイに書けるが
エンジン側の都合なのでどうしようもなさそうである…

【UE5】 CommmonUIとRetainerBoxを使用した際に遭遇した問題

CommmonUIプラグインでCommonActivatableWidgetStackを使用して
画面遷移を作成した際に遭遇した問題です。

発生状況

CommonActivatableWidgetStackにAddWidgetでWidgetを追加したときに
追加したWidgetの中身にOverlayが親になっているRetainerBoxがあると以下の警告ログが表示される。

The requested size for SRetainerWidget is 0. W:0 H:0

RetainerBoxの子にはimageが一つだけ置いてあり
SetBrushFromSoftTexture
で画像の差し替えを行っていました。

解決策

調査したところ
CommonActivatableWidgetStackの基本機能の画面遷移の問題のようで

Transitionの時間を0にするとログは出なくなります。

Transitionをつけたい場合は以下のような方法がありました。
– RetainerBoxの親にCanvasPanelを配置する
– Fadeが終わったタイミングでRetainerBoxをVisibleにする

Fadeが終わったタイミングでRetainerBoxをVisibleにする
こちらの方法は
画面のFadeが終わったタイミングで表示を呼ばないとうまく動作しないようでした。
例 : Transition = 0.4に指定した場合
fadeInに0.2s fadeOutに0.2sかかるので
Constructが呼ばれてから0.2sより後にRetainerBoxをVisibleにすれば
ログは消えました。

しかしFadeOut中に透明な状態が見えてしまうので対応は難しそうでした。

かなりのレアケースな問題ですが
ネットに情報がなくて困ったのでメモしておきます。