【Unreal Engine】スプラッシュスクリーンをドラッグで移動できるようにする(Windows専用)【UE4】

この記事は、Unreal Engine のソースコードを変更し、エディタ起動時に表示されるスプラッシュスクリーンをドラッグして移動できるようにする方法について説明しています。

執筆時に扱った Unreal Engine のソースコードのバージョンは 4.25.1
プラットフォームは Windows 10 (64ビット版) を対象としています。
ビルドに使用したアプリ(IDE)は Microsoft Visual Studio 2017 です。

以降、Unreal Engine 4 を UE4 と略記します。 


 

念のため、お断り

ここで説明する内容は、UE4 のエディタのソースコードを変更する方法です。
エディタ拡張の話ではありません

UE4 のソースコードをダウンロードする

ソースコードのダウンロード方法は、公式のドキュメントを見れば分かります(多分)。

私は頻繁に更新するつもりはないので、Zip でダウンロードしました。

UE4 のソースコードをビルドする

こちらも公式にドキュメントがあります。

最初にビルドして、ビルドが通ることを確認できてからソースコードを変更します。
ビルドは長くても40分くらいと書かれていますが、私のPCだと1時間以上かかりました。
内蔵SSDとコアが沢山あるCPUじゃないとキツいかも知れません。

スプラッシュスクリーンってなに?

UE4 起動時に表示されるコレです。

これ、ディスプレイの真ん中から移動しません。
別のウィンドウを上に重ねてしまえば見えなくなるのですが、画面の端っこに移動させて、今どれくらい読み込みが終わったのかを確認しながら、UE4 が起動するまでの間に別の作業をしたいです。

欲を言えば、前に表示していた位置を保存しておき、次回また表示するときは、保存しておいた位置に表示してくれると良いですね。

スプラッシュスクリーンの仕組み

このスプラッシュスクリーンは Windows の場合、Windows の古い API を使って表示しています。
具体的に言うと、CreateWindowEx() と WndProc() とメッセージループと呼ばれる方法を使っています。
20年以上前に使われていたものです。

UE4 には Slate という仕組みがありますが、スプラッシュスクリーンの表示には使っていません。
なので、スプラッシュスクリーンに何か機能を追加するには、直接ソースコードをいじる必要があります。

一行追加するだけでOK

スプラッシュスクリーンをドラッグして移動できるようにするのに必要なコードは、たったの一行です。
変更するソースファイルは Engine/Source/Runtime/ApplicationCore/Private/WindowsPlatformSplash.cpp です。

176 行目に case WM_NCHITTEST: return HTCAPTION; を挿入します。

上書き保存してビルドすれば、スプラッシュスクリーンをドラッグで移動できるようになります。


スプラッシュスクリーンをドラッグして右下に移動してみた。

見た目も変えちゃう

Engine/Content/Splash フォルダに、スプラッシュスクリーンとして表示する画像があるので、これを変更すればスプラッシュスクリーン自体も変更することができます。

スプラッシュスクリーンの表示位置を読み込んで保存する

せっかくなので、スプラッシュスクリーンを表示していた位置を保存し、次回表示するときは、保存しておいた場所に表示されるようにしてみます。

保存用ファイルを作成

保存用のファイルを作成します。
ファイル名は SplashScreen.ini にしました。
このファイルを置く場所はどこでも良いと思いますが、今回は Engine/Saved/Config/Windows/ にしました。
このファイルをテキストエディタで開いて、以下の設定を書き込み、保存します。

[Position]
X = -1
Y = -1
ファイルパスを保持する変数を追加

スプラッシュスクリーンの処理を書き換えます。
3か所にコードをコピペするだけです。
書き換えるソースファイルは、スプラッシュスクリーンをドラッグ移動できるようにしたときと同じ Engine/Source/Runtime/ApplicationCore/Private/Windows/WindowsPlatformSplash.cpp です。

このファイルの 50 行あたりにスタティック変数の宣言が並んでいるので、その下に以下のコードを追加します。

//**

static const TCHAR* GSplashScreenIni = NULL;

//**

こんな感じ

スプラッシュスクリーンの表示位置を保存する処理を追加

170 行あたりに case WM_DESTROY: と書かれた行があるので、その下に以下のコードを追加します。

{
	WINDOWINFO WindowInfo;
	GetWindowInfo(hWnd, &WindowInfo);
	const LONG WindowPosX = (LONG)WindowInfo.rcWindow.left;
	const LONG WindowPosY = (LONG)WindowInfo.rcWindow.top;
	const int32 BufferSizeBytes = 16;
	TCHAR* Buffers = new TCHAR[BufferSizeBytes];
	_stprintf_s(Buffers, BufferSizeBytes, TEXT("%ld"), WindowPosX);
	BOOL bSuccess = WritePrivateProfileString(TEXT("Position"), TEXT("X"), Buffers, GSplashScreenIni);
	if (bSuccess)
	{
		_stprintf_s(Buffers, BufferSizeBytes, TEXT("%ld"), WindowPosY);
		bSuccess = WritePrivateProfileString(TEXT("Position"), TEXT("Y"), Buffers, GSplashScreenIni);
	}
	delete[] Buffers;
}

こんな感じ

保存した値を読み込む処理

450 行あたりに

int32 ScreenPosX = …
int32 ScreenPosY = …

と書かれた行があるので、この2行を以下のコードで書き換えます。

//**
GSplashScreenIni = *FPaths::ConvertRelativePathToFull(FPaths::EngineContentDir() + TEXT("..\\Saved\\Config\\Windows\\SplashScreen.ini"));
const int32 PositionX = GetPrivateProfileInt(TEXT("Position"), TEXT("X"), -1, GSplashScreenIni);
const int32 PositionY = GetPrivateProfileInt(TEXT("Position"), TEXT("Y"), -1, GSplashScreenIni);
const int32 ScreenPosX = PositionX >= 0 && PositionX < GetSystemMetrics(SM_CXSCREEN) ? PositionX : (GetSystemMetrics(SM_CXSCREEN) - WindowWidth) / 2;
const int32 ScreenPosY = PositionY >= 0 && PositionY < GetSystemMetrics(SM_CYSCREEN) ? PositionY : (GetSystemMetrics(SM_CYSCREEN) - WindowHeight) / 2;
//**

こんな感じ

ビルドして実行

ビルドして実行すれば確認できます。
エラーが出た場合は、以下の順番に見直してみて下さい。

  1. Unreal Engine のソースコードのバージョンは 4.25.1 か?
  2. ソースコードを一切書き換えない状態でビルドは通るか?
  3. コピペ内容、コピペ位置を間違えていないか?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です