ジャンプの途中でゲームを止めると、キャラクターは空中で静止する。それでも、手前の「再開」ボタンは押せる。ポーズメニューでは、ゲームの世界を止めながら、メニューの操作は受け付ける必要があります。
Set Game Paused でゲームを止めるだけでは、入力先やカーソルまでは切り替わりません。この記事では、それぞれの役割を整理し、Pキーで開き、同じキーでもボタンでも再開できるメニューを作ります。

この記事でわかること
- ゲームの停止と、メニュー操作が別だということ
- Set Game Pausedと、入力がどこへ届くかの関係
- 開く処理と閉じる処理を組にして書く手順
- 止めても動いてしまうものへの対処
この記事で作るもの
- Pキーでゲームが止まり、画面中央にメニューが出る
- 「再開」で止めた続きへ戻り、「最初から」で同じレベルをやり直す
- 閉じた後も移動・視点操作ができ、何度でも開き直せる
対象は、UE5のThird Personテンプレートを使う、キーボードとマウスで操作する1人用ゲームです。Blueprintの変数・関数を作ったこ とがあり、UMG入門のWidget作成とボタン操作が分かる方を想定しています。
ゲームの停止と、メニュー操作は別
Set Game Paused のPausedをオンにするとポーズ、オフにすると解除です。Return Valueは、ポーズ・解除に成功したかを表すBooleanです。
ポーズ中は、通常のActorのTickやゲーム用Timer、物理シミュレーションなどが進まなくなります。Tickは、動きなどをフレームごとに更新する処理。Timerは、「1秒後に処理する」といった予約です。ジャンプ中に止めると落下が止まり、解除するとそこから続きを計算します。
一方、画面に重ねたUMGのボタンは操作できます。ただし、表示されていることと、クリックを受け取れることは別です。メニューを開くときには、次の3つをそろえます。
| 変えるもの | 使う設定 | 今回の役割 |
|---|---|---|
| ゲームの進行 | Set Game Paused | キャラクターや物理を止める |
| 入力の行き先 | Set Input Mode Game And UI | メニューを優先して操作する |
| ポインターの表示 | Show Mouse Cursor | 押す場所が分かるようにする |
「メニューが見えるのに押せない」場合は、ポーズの成否だけでなく、入力先とカーソルを確認します。この3つを分けて考えると、設定を手当たり次第に変えずに済みます。

入力はどこへ届くのか
Input Modeは、キーボードやマウスの入力を、ゲームとUIのどちらへ渡すかを決めます。プレイヤーの操作を受け持つPlayer Controllerを指定して切り替えます。
| モード | 入力の扱い | 今回の使い方 |
|---|---|---|
| Game Only | ゲーム側で受ける | 通常のプレイ中 |
| UI Only | UI側 で受ける | 今回は使わない |
| Game And UI | UIが先に受け、処理しなかった入力をゲーム側へ渡す | ポーズメニューを開いている間 |
Game And UIは、1回の操作を常に両方へ送る設定ではありません。たとえば、ボタンのクリックはUIが処理し、UIが使わないPキーはPlayer Controllerへ届きます。今回は、そのPキーでメニューを閉じます。UI側へ独自のキー処理を追加するときも、Pキーを処理済みにしないことが前提です。公式の入力モードの説明

ポーズ中にも、閉じるキーを受け取る
入力先をGame And UIにしても、Enhanced Inputのアクションには、ポーズ中に動かすための設定が必要です。ポーズ用のInput Actionだけ、Trigger When Pausedをオンにします。
Input Actionは「ジャンプ」「ポーズ」のような操作の名前を持つアセットです。キーとの対応は別の Input Mapping Context(IMC) に登録します。今回は「Pキー → ポーズ」という対応を1つ追加します。
UI Onlyでも、Widget側でキーを受けて閉じる方式は作れます。ただし、この記事のようにPlayer ControllerのInput Actionで開閉する方式とは配線が変わります。ま ずはGame And UIで最後までそろえましょう。
実践1:ポーズ用のPキーを用意する
1. 練習用のレベルとControllerを作る
Third Personテンプレートのレベルを「Save Current Level As」で L_PausePractice として保存します。後で「最初から」ボタンから、このレベルを開き直します。Pキーを使うのは、エディタ内のPlayではEscキーがプレイ終了に使われるためです。
- 「World Settings」の「GameMode Override」を確認します。Noneなら「Project Settings → Maps & Modes」のDefault GameModeを確認します。
- 現在使っているGameModeのBlueprintをコンテンツブラウザで複製し、
BP_PausePracticeGameModeと名付けます。Default Pawn Classなど、元の設定は引き継ぎます。 - 元のGameModeの「Class Defaults」で、Player Controller Classを確認します。そのクラスがBlueprintなら、アセットを右クリックして「Create Child Blueprint Class」を選び、
BP_PausePracticeControllerと名付けます。標準のPlayerControllerなら、PlayerControllerを親に新しいBlueprintを作ります。 - BP_PausePracticeGameModeのPlayer Controller Classを、BP_PausePracticeControllerへ変更します。
- L_PausePracticeのGameMode Overrideへ、BP_PausePracticeGameModeを指定して保存します。
子Blueprintは、元のクラスの処理を引き継いで追加できるクラスです。テンプレート側に入力の初期設定がある場合も、それを残してポーズの処理を加えます。
Playして、これまでどおり移動・ジャンプ・視点操作ができるか確認してください。ここで動かなくなった場合は、先へ進まず、元のGameModeとControllerの設定を見直します。
2. ポーズ専用の入力を追加する
コ ンテンツブラウザの「Input」から、次の2つを作ります。

| アセット | 設定 |
|---|---|
Input Action IA_PausePractice | Value Type=Digital(bool)、Trigger When Paused=オン、TriggersとModifiersは空 |
Input Mapping Context IMC_PausePractice | MappingsにIA_PausePracticeを追加し、キーをPにする。こちらのTriggersとModifiersも空 |
BP_PausePracticeControllerのイベントグラフを開きます。親がBlueprintの場合は、Event BeginPlayで先に親のBeginPlayを実行し、その後へ Add Mapping Context を追加します。親の呼び出しがない場合は、Event BeginPlayを右クリックして「Add Call to Parent Function」を追加します。標準のPlayerControllerを親に新規作成した場合は、Event BeginPlayから直接Add Mapping Contextへ進みます。
Add Mapping ContextのTargetには、Selfから取得したEnhanced Input Local Player Subsystemを渡します。グラフへSelfを置き、青い出力から Get Enhanced Input Local Player Subsystem を検索します。これは、そのプレイヤーの入力の対応表を管理するものです。Mapping ContextにIMC_PausePractice、Priorityに10を指定します。
BP_PausePracticeController:イベントグラフ
Event BeginPlay
→ Parent: BeginPlay
→ Add Mapping Context
Target: Selfから取得したEnhanced Input Local Player Subsystem
Mapping Context: IMC_PausePractice
Priority: 10

元の移動用IMCは残します。Clear All Mappingsは使いません。ポーズ用の対応表はプレイ中ずっと登録し、閉じるときも削除しません。
次に、同じグラフでIA_PausePracticeのイベントを検索し、Startedから Print String をつなぎ、In StringをPause keyにします。今回の設定では、Startedは押した瞬間に1回実行されます。押している間に繰り返すTriggeredは、開閉の切り替えには使いません。
Playして画面をクリックし、Pを押すたびに文字が1回出れば、入力の準備は完了です。このPrint Stringは、後でメニューの開閉へ差し替えます。
実践2:2つのボタンを並べる
User Widgetを親に WBP_PausePracticeMenu を作り、Designerで次の階層を組みます。Canvas Panelがなければ、最初にルートとして追加します。
Canvas Panel
└─ Size Box
└─ Vertical Box
├─ Text「PAUSED」
├ ─ Button「ResumeButton」
│ └─ Text「再開」
└─ Button「RestartButton」
└─ Text「最初から」
| 対象 | 設定 |
|---|---|
| Size BoxのCanvasスロット | Anchors=中央、Alignment=0.5 / 0.5、Position=0 / 0、Auto Size=オン |
| Size Box | Width Override=オンで360。Height Overrideはオフ |
| PAUSEDのText | Font Size=32、Color and Opacity=濃紺、Justification=中央、Vertical Boxスロットの下Padding=16 |
| 2つのButton | Is Variable=オン、Is Enabled=オン、Is Focusable=オン。Vertical Boxスロットは横Fill、上下Padding=6 |
| ボタン内のText | Font Size=24、Color and Opacity=濃紺。Buttonスロットの横・縦Alignment=中央、Padding=12 |
| ButtonのStyle | NormalのTint=薄い灰色、HoveredのTint=青。カーソルを乗せた変化が分かる色にする |

Anchorsは画面内の配置基準、AlignmentはWidget自身のどこをその基準へ合わせるかです。両方を中央にすることで、画面サイズが変わってもメニューの中心を画面の中心へ置けます。
コンパイル・保存します。今はメニューの 見た目だけを作った段階なので、Playしてもまだ表示されません。
実践3:開く・閉じる処理を組にする
BP_PausePracticeControllerへ、変数 PauseMenuWidget を作ります。型は WBP_PausePracticeMenu Object Reference、初期値はNoneです。
参照は、作ったWidgetを後から指定するためのものです。今回は「表示中のメニュー」をこの変数へ保存します。Noneは、まだメニューを指定していない状態。閉じたらNoneへ戻す、という約束で開閉を判定します。
「My Blueprint」のFunctionsの「+」で、引数なしの関数を3つ作ります。名前は OpenPausePractice、ResumePausePractice、RestartPausePractice です。いったんコンパイルしてから、順に中身を作ります。
1. メニューを作り、操作できる状態にする
OpenPausePracticeの関数グラフに Create Widget を置きます。ClassはWBP_PausePracticeMenu、Owning PlayerにはSelfを渡します。このグラフのSelfは、今操作しているPlayer Controller自身です。
Create WidgetのReturn Valueを Set PauseMenuWidget の値へつなぎます。白い実行線はCreate WidgetからSetへ。その後、次の順につなぎます。
| 順番 | ノード | 入力・設定 |
|---|---|---|
| 1 | Add to Viewport | Target=PauseMenuWidget、ZOrder=100 |
| 2 | Set Input Mode Game And UI | Player Controller=Self、In Widget to Focus=PauseMenuWidget内のResumeButton、Mouse Lock=Do Not Lock、Hide Cursor During Capture=オフ、Flush Input=オフ |
| 3 | Set Show Mouse Cursor | Target=Self、値=オン |
| 4 | Set Game Paused | Paused=オン |

ZOrderは、重なったWidgetの前後関係です。大きい値ほど手前へ出ます。今回はメニューを手前にし、最後にゲームを止めます。
フォーカスは、キーボードで操作する対象が選ばれている状態です。ここではメニュー全体ではなく、最初に操作したい「再開」ボタンを指定します。Get PauseMenuWidgetの青い出力から Get ResumeButton を検索し、その出力をIn Widget to Focusへつなぎます。ButtonをIs Variableにしたのは、このようにグラフから指定するためです。

取り出したボタンを、最初の選択先として渡します。

2枚目のGet ResumeButtonは、1枚目で作った同じノードの続きです。もう1つ作る必要はありません。白い実行線はAdd to Viewportの後につなぎます。
OpenPausePractice
→ Create Widget(Class: WBP_PausePracticeMenu、Owning Player: Self)
→ Set PauseMenuWidget(値: Create WidgetのReturn Value)
→ Add to Viewport(Target: PauseMenuWidget)
→ Set Input Mode Game And UI(Player Controller: Self)
→ Set Show Mouse Cursor(Target: Self、オン)
→ Set Game Paused(Paused: オン)
Set Show Mouse Cursorは、ControllerのShow Mouse Cursor変数をSetしたノードです。「Show Mouse Cursor」で検索するか、Selfの青い出力から検索します。入力モードを変えるだけでは、この表示設定までは切り替わりません。
2. ゲームを再開し、メニューを片付ける
ResumePausePracticeには、次の順でノードを置きます。この関数は、メニューが開いているときに呼びます。
| 順番 | ノード | 入力・設定 |
|---|---|---|
| 1 | Set Game Paused | Paused=オフ |
| 2 | Remove from Parent | Target=PauseMenuWidget |
| 3 | Set PauseMenuWidget | 値=None |
| 4 | Set Input Mode Game Only | Player Controller=Self、Flush Input=オン |
| 5 | Set Show Mouse Cursor | Target=Self、値=オフ |

Noneを入れるには、新しいSet PauseMenuWidgetを置き、値の入力ピンへ何もつながない状態にします。初期値Noneが入ります。
画面から外すことと、参照を空にすることは別です。 Remove from Parentだけでは、変数はそのWidgetを覚えています。後で「メニューがあるか」を調べるので、閉じたことが分かるよう、参照もNoneへ戻します。
Flush Inputは、それまでの入力状態をクリアする設定です。再開したら、移動キーなどを改めて押して確認します。

図の上段はOpenPausePracticeの最後、下段はResumePausePracticeの最後です。別々の関数の続きとしてつなぎます。
3. 「最初から」は、再開してからレベルを開き直す
RestartPausePracticeでは、まず Resume Pause Practice を呼び、その実行出力から Open Level (by Name) へつなぎます。Level Nameは L_PausePractice、Absoluteはオン、Optionsは空です。
RestartPausePractice
→ Resume Pause Practice(Target: Self)
→ Open Level (by Name)(Level Name: L_PausePractice)
「再開」は現在の位置から続きを遊びます。「最初から」はレベルを読み直すので、キャラクターも開始位置へ戻ります。どちらも同じResumePausePracticeを通すことで、入力やカーソルの戻し忘れを防ぎます。
ここでレベル名を手入力できるのは、実践の最初にその名前で保存したためです。自分のレベルへ組み込むときは、Level Nameも保存したアセット名へ合わせてください。
実践4:キーとボタンをつなぐ
Pキーで、開く・閉じるを選ぶ
BP_PausePracticeControllerのイベントグラフへ戻ります。先ほどのPrint Stringを外し、IA_PausePracticeのStartedを Branch へつなぎます。
Get PauseMenuWidgetから、白い実行ピンのない Is Valid を作り、そのBoolean出力をBranchのConditionへ渡します。Is Validは、参照先を使えるかどうかを調べるノードです。
- True側:
Resume Pause Practice(Target=Self)を呼ぶ - False側:
Open Pause Practice(Target=Self)を呼ぶ

今回の約束では、参照があれば開いているので閉じ、Noneなら新しく開きます。別の場所からメニューだけを外したり、PauseMenuWidgetを上書きしたりせず、開閉はこの2関数へ集めます。
コンパイルしてPlayします。Pでメニューが出てゲームが止まり、いったんPを離してもう一度押すと閉じれば、キーに よる開閉はできています。
ボタンからControllerの処理を呼ぶ
WBP_PausePracticeMenuのDesignerでResumeButtonを選び、DetailsのEventsからOn Clickedを追加します。RestartButtonにも同じイベントを作ります。
それぞれのイベントから Cast To BP_PausePracticeController へ白い線をつなぎます。CastのObjectには、Widget内で置いた Get Owning Player のReturn Valueを渡します。
Get Owning Playerで取得するのは、Create WidgetのOwning Playerへ渡したControllerです。Castは、それを今回作ったクラスとして扱い、専用の再開関数を呼べるようにする処理です。
| ボタンのイベント | Cast成功の実行出力から呼ぶ関数 | 関数のTarget |
|---|---|---|
| ResumeButtonのOn Clicked | Resume Pause Practice | CastのAs BP Pause Practice Controller |
| RestartButtonのOn Clicked | Restart Pause Practice | CastのAs BP Pause Practice Controller |
Cast Failedには Print String をつなぎ、Pause controller mismatchと出すようにします。この文字が出たら、練習レベルのGameModeとPlayer Controller Class、Create WidgetのOwning Playerを確認します。

図はResumeButtonの接続です。RestartButtonも同じ形で、最後の呼び出しをRestart Pause Practiceに変えます。
Widget側でSet Game Pausedやカーソル設定をもう一度組む必要はありません。ボタンは「再開して」「最初からにして」とControllerへ頼むだけにします。
動かして確かめる
両方のBlueprintをコンパイル・保存してPlayします。ゲーム画面をクリックして操作を始めてください。
| 操作 | 確かめる結果 |
|---|---|
| 歩いてからジャンプ中にPを押す | キャラクターが空中で止まり、メニューとカーソルが出る |
| 「再開」へカーソルを乗せる | ゲームが止まったまま、ボタンの色が変わる |
| 「再開」を押す | メニューが消え、止まった位置から落下の続きが始まる |
| 移動・マウスでの視点操作を試す | 通常どおり操作でき、メニュー用カーソルは残らない |
| Pを押して離し、もう一度Pを押す | キーだけでも開閉できる |
| 少し移動してからPを押し、「最初から」を押す | レベルを開き直し、開始位置から操作できる |
| さらにPで開閉する | 2回目以降も、メニューが重ならずに開閉できる |
「見えた」で終 わらず、再開後の操作と、次の開閉まで確かめるのがポイントです。

うまくいかないとき
| 症状 | 確認する場所 |
|---|---|
| 最初のPから反応しない | IMC_PausePracticeの登録、GameMode Override、Controllerの親BeginPlay、ゲーム画面へ入力が届いているか |
| 長押しで何度も開閉する | IA_PausePracticeのStartedを使っているか。Triggersに別の条件を追加していないか |
| Pで開くが、Pで閉じない | Trigger When Pausedがオンか。Game And UIか。UI側でPキーを処理済みにしていないか |
| ボタンをクリックできない | Input Mode、Show Mouse Cursor、ButtonのIs Enabled |
| ボタンは反応するが閉じない | Cast FailedのPrint。Cast成功の実行線と、関数のTargetの接続 |
| 2回目に開けない | ResumePausePracticeでPauseMenuWidgetをNoneへ戻しているか |
| 再開後に操作できない | Game Onlyへ戻したか。移動キーを押し直したか |
| 「最初から」で読み直せない | L_PausePracticeを保存したか。Open LevelのLevel Nameが一致するか |
ポーズ そのものを切り分けたい場合は、Set Game PausedのReturn Valueや Is Game Paused をPrint Stringへ出します。キーが届かないのか、停止に失敗しているのかを分けて追えます。
おまけ:止めるものを選びたいとき
音も同じように止まるとは限りません。 ポーズ中に再生するかは、Audio ComponentのIs UI Soundなどの設定で変わります。「音はすべて止まる」「音は対象外」と決めつけず、BGM・効果音・メニュー音をそれぞれ確認します。特定のAudio Componentを明示的に止めたい場合は Set Paused を使えます。Audio Componentの公式設定
ポーズ中もActorのTickを実行したい場合。 Class DefaultsのActor TickにあるTick Even when Pausedで許可できます。ただし、Tickを呼ぶことと、ゲーム内の時間を進めることは別です。これだけで物理や、そのActorの全Componentまで通常どおり動くわけではありません。今回のメニュー操作のために、キャラクター全体へオンにする必要はありません。
タイトルや設定画面へ広げるなら。 タイトルへ戻るボタンは、今回のやり直しと同じく後片付けをしてから、保存済みのタイトル用レベルを開きます。Open Levelの記事が続きになります。設定用Widgetへ切り替える場合は、表示だけでなく、最初に選ぶボタンへのフォーカスも渡します。
オンラインのメニューは別に考えます。 この記事は1人用です。対戦中に自分のメニューを開く場合は、他のプレイヤーのゲーム進行まで止める設計にはせず、自分の操作とUIを切り替えます。
まとめ
ポーズメニューは、ゲームの停止・入力先・カーソルを切り替え、閉じるときに元へ戻す仕組みです。今回は、ポーズ用のInput Actionを止めずに受け取り、Pキーとボタンから同じ再開処理を呼びました。
まずは、ジャンプ中に止めて、ボタンを押すと続きから落下する感触を確かめてみてください。そこまでできれば、「ゲームは止まっているのにメニューは操作できる」という2つの動きを、自分の手で組めています。
参考:Set Game Paused、Enhanced Input、Input Actionのポーズ設定、ActorのTick