ゲーム開発備忘録

ゲームプログラマー UE4・5向けの記事を書いておりますので見ていただけるとありがたいです。

【UE4・UE5】〈Tips〉PCのウィンドウの仕組みをUEで再現してみよう

目次

 

今年もアドベントカレンダー2025の季節になりました。

毎年 実用的な内容から挑戦した体験談まで素敵な記事がたくさん掲載されています。

無料で全て読めてしまうので、ぜひ見に行ってみて下さい。

qiita.com

はじめに

今回はPCのウィンドウタブのような仕組みを作る方法について解説します。

技術的な共有というよりはこういう組み方をするとできるよといった感じの実装例です。PC画面をゲーム内に登場させたようなケースで参考になる(かも?)しれません。



構成としてタブ本体のベースクラス・派生したインスタンス・タブスポナーの3つを順番に作って完成を目指します。

 

個人の備忘録としてまとめています。誤った情報がある場合があります。

コメントにてご指摘のほどお願いいたします。

 

UE5.4で解説しますがどのバージョンでも可能な機能で作ります。

 

解説

① ウィンドウのベースWidget - Widgetの作成 -

まずはウィンドウ本体を作っていきます。

使いまわしが効くようにNamedSlotを活用したベースウィジェットを作ります。

コンテンツブラウザを右クリックしユーザーインターフェース->ウィジェットブループリント、

 

UserWidgetを選択します。

 

名前はW_WindowBaseとしました。

 

② ウィンドウのベースWidget - デザインの作成 -

作成したウィジェットを開きデザインを組んでいきます。
ここでの縦横比や名前などは後の実装でインスタンスなどで上書きされるので気にしなくても大丈夫です。



以下のような構造でできています。太字が変数化(IsVariable)しているものです。

 

W_WindowBase
└── CanvasPanel
    └── WindowPanel (CanvasPanel)
        ├── OutLine (Image)
        └── VerticalBox
            └── HorizontalBox
                ├── TabButton (Button)
                │   └── TabName(TextBlock) "Window Name"
                └── CloseButton (Button)
                    └── TextBlock "×"
            └── Overlay
                ├── WindowBackGround (Image)
                ├── FocusButton (Button)
                └── NamedSlot

設定画像を閉じるにはここクリック

変更なし

 

 アンカーは左上サイズを仮で500を入れています。

 

 ウィンドウ境界が分かるようにアウトラインを入れています。
アンカーは画面全体。色は薄い灰色にしています。

 

ウィンドウのコンテンツ本体です。

アンカーは画面全体。

上のアウトラインが出るようにオフセットを少し入れています。


上部のタブ項目のためのホリゾンルボックスです。
特に変更はありません。

 

タブのボタンです。このボタンがウィンドウの移動を検知するトリガーとなります。

フィルの設定とカラーをそれぞれ適応しています。

 

ウィンドウの文字設定です。フォント・サイズ・色・アラインメントはお好みで。

 

閉じるボタンです。

カラーはお好みで。

 

閉じるボタンのテキストです。

 

コンテンツ本体を置くためのオーバーレイです。

全体を覆うようにしましょう。

 

コンテンツ自体の背景です。

透過するとOutlineのカラーが出てしまうので不透明に設定しています。

インスタンスでカラーを変えたい人はココを変数化しても良いかもしれません。

 

ウィンドウが触られたことを検知するためのボタンです。

すべて透過表示になるようにカラーを設定しています。

必ずNamedSlotより上の階層になるように配置しましょう。


インスタンスでコンテンツを置けるようにするためのNamedSlotです。

 

 

③ ウィンドウのベースWidget - Widgetの実装 -

 

デザインからイベントに移動します。必要な変数はこちらです。

 

各変数は以下の通り

変数画像を閉じるにはここクリック

ウィンドウの名前を表示する文字列です。デフォルト値を入れています。

ウィンドウの大きさを決めるプロパティです。デフォルト値を入れています。

このタブが何個目に追加されたかを記録する変数です。初期位置の決定で利用します

マウスがウィンドウを触った位置とウィンドウからの相対位置をキャッシュするための変数です。

ホバー中の更新イベントのハンドルです。

このウィジェットを管理する上位のクラスのためにウィンドウが触られたときのデリゲードを用意します。Inputに自身のWidgetの参照を返すようにしています。

 

これらの変数を利用して実装を書いていきます。

 

初期化処理

▼プロパティをUIに反映する処理です。

 

▼LayerIdからタブが重複しないようにズラす処理です。

 

Windowの位置更新

▼タブを押しているときのイベント

 

▼画面内にウィンドウを制限する処理

 

▼ボタンからのイベントです

 

最後にこのBaseWidgetはインスタンスとして利用されるのが目的のため、

インスタンスの選択肢に出ないようにクラス設定からAbstractClassに指定しましょう。

 

④ ウィンドウインスタンスの実装 -アセット作成-

W_WindowBaseを使って具体的なインスタンスを作っていきます。

 

コンテンツ右クリックからウィジェットブループリントを作ります。

 

ここでUserWidgetではなくW_WindowBaseを指定します。

 

名前はW_Window_TypeAとしました。

そうするとW_WindowBaseを継承したUIを作ることができました。

 

同様にW_Window_TypeB,W_Window_TypeCも作りました。

 

多様化させるためにそれぞれ以下の設定をしてみました

W_Window_TypeA

警告風のウィンドウ

 

クラスのデフォルトもしくはデザイナーの一番上を選択するとWindowSizeや名前などを変えれます。

 

W_Window_TypeB

画像とテキストだけおいた天気予報風ウィンドウ

 

W_Window_TypeC

以前記事で書いたTwitterSNSの紹介で作った機能を入れてみました。

 

↓解説記事

namiton.hatenablog.jp

 

ここまでセットアップができたらウィンドウのセットアップは完了です!

⑤ フレームウィジェットの実装 - Widgetの作成-

Windowを生成を行うフレームウィジェットを作成していきます。

手順は上のUserWidgetと同じです。

名前はW_Frameにしました。

 

⑥ フレームウィジェットの実装 - デザインの実装-

タスクアイコン的なものを作ってみました。

 

 

 

以下のような構造でできています。太字が変数化(IsVariable)しているものです。

W_Frame
└── CanvasPanel
    └── Overlay
        ├── BackGround
        └── HorizontalBox
            ├── ScaleBox0
            │   └── SpawnWindowButton_TypeA
            ├── ScaleBox1
            │   └── SpawnWindowButton_TypeB
            └── ScaleBox2
                └── SpawnWindowButton_TypeC

 

⑦ フレームウィジェットの実装 - 実装-

 

アイコンを押すとウィンドウを生成するサンプル実装です。

 

TypeA~Cのボタンに合わせて生成するWidgetを登録する仕組みです。

 

関数SpawnWindowのインプットはW_WindowBaseのクラス参照です。

 

Widgetの生成とLayerIdの登録、フォーカスの設定をしています。

CamvasPanelに再度AddChildすることで階層を制御しているのがポイントです。

 

最後にレベルBPなどにFrameWidgetの追加とマウス制御のロジックをいれて完成です。

 



最後に


UE4やUE5向けの記事を書いています。

皆様の応援が投稿のモチベーションになりますので

コメントやX(Twitter)のフォローなどしていただけるとありがたいです。

それではよきゲーム開発を。

投げ銭を投げる