UE5 のローカルマルチプレイヤーを 1 つのデバイスで操作する
第21回UE5ぷちコン|株式会社ヒストリア で以下の作品を提出しました。
第21回UE5ぷちコン 提出動画「Hand Push Sumo」 - YouTube
ゲームを作るにあたり、さくっと遊ぶために「キーボード一つあれば遊べる」ようにしたかったので、タイトルにもある「ローカルマルチプレイヤーを1つのデバイスで操作する」方法を調べました。
簡単なローカルマルチプレイヤー
以下の2つの記事がとても参考になります。
基本的には以下の Create Local Player ノードを呼び出すだけでよく、とても簡単です。

ですがこの場合、PlayerController がプレイヤーの数だけ作成され、インプットデバイスも同様数が必要になります。
一つはキーボードでいいとしても、もう一つゲームパッド等が必要になるわけです。
キーボード一つのインプットデバイスでローカルマルチプレイヤーを構築する
GitHub - dany1468/LocalMulti1Device
今回試したコードは上記で管理しています。UE 5.3.2 で実行できます。
今回試したのは以下の3パターンです。
- 分割無しの一つの画面
/Maps/SingleViewMap
 - 2分割された画面で、最初からキャラクターは配置しておく
/Maps/SeparateViewMap
 - 2分割された画面で、ゲーム開始時にキャラクターを Spawn する
/Maps/SeparateViewWithPlayerStartMap
 
| 分割無し | 2分割 | 
|---|---|
![]()  | 
![]()  | 
以下では簡単にそれぞれの方法を見ていきます。
キャラクター
上記のいずれのパターンでもキャラクターは単純なもので一つの BP (BP_PlayerCharacter) です。
![]()  | 
![]()  | 
プロジェクトを直接見てもらうのが早いですが、 PhysicsConstraint は Cube と Sphere をつないでおり、Sphere が前方方向にのみ動くように設定しています。

Event Graph も単純なものです。今回の本題とは外れるので内容は省略します。
パターン1: 分割無しの一つの画面
/SingleView/PC_SingleView が PlayerController です。GameMode である GM_SingleView もありますが、Event Graph はなく Default の設定だけです。
以下が PC_SingleView の Begin Play です。

まず、ここまでで「 Create Local Player ノードを利用していないこと」がポイントです。つまり、PlayerController は一つしか無いということです。
次に、 SingleViewMap レベルには BP_PlayerCharacter を 2 プレイヤー分配置し、それぞれ Player1, Player2 のタグを付けてあります。
上記では、Get All Actors with Tag を使って配置してあるキャラクターを取得し、 PlayerController に保存しています。
続いて、以下が PC_SingleView の Action 部分です。

見ての通りで、 Begin Play で保存した両方のキャラクターの参照に対して Push を実行しています。
こうすることで、一つのデバイスで2つのキャラクターの対戦を実現できます。
ちなみに、
Player 0は2つのキャラクターを映すカメラに Possess させています。
パターン2: 2分割された画面で、最初からキャラクターは配置しておく
まず、PlayerController は先程と同じ /SingleView/PC_SingleView を利用しています。つまり SeparateViewMap には、同様にタグの付いたキャラクターを配置しています。
そして GameMode を変更し GM_SeparateView を用意しています。

今回は画面を分割しているので Create Local Player ノードを利用しています。
2つの PlayerController が出現することになりますが、レベルに配置済のキャラクターにはタグだけではなく Auto Possess Player にそれぞれ Player 0, Player 1 を設定し、それぞれの PlayerController に対応させています。
しかし、最終的に利用するのは 1つ目のインプットデバイスに紐づく 1 つ目の PlayerController だけです。今回のコードだと、利用しない 2 つ目の PlayerController でも Begin Play が実行されてしまいますが、利用しないのでスルーします。
パターン3: 2分割された画面で、ゲーム開始時にキャラクターを Spawn する
まず、レベル上には PlayerStart を2つ配置します。それぞれの Player Start Tag に Player1, Player2 を設定しておきます。

ここでは GameMode と PlayerController の両方を作成します。 GM_SEparateViewWithPlayerStart と PC_SeparateViewWithPlayerStart が該当します。
操作に関してはここまでと同様で、一つの PlayerController で両方のキャラクターを操作できるようにしておきます。
重要なのはキャラクターの配置部分です。

ここは PlayerStart を利用してそれぞれのキャラクターを配置しています。
一つ前の例と違って、キャラクターの配置まで重複して実行して欲しくないので、ここのコードでは PlayerController の初期化処理を Begin Play に任せず、 GameMode から明示的に1つ目の PlayerController の初期化処理だけ呼ばれるようにしています。
まとめ
さらっとした感じでまとめましたが、この仕組みを実装する前は「インプットデバイス」と PlayerController の関係も正しく理解しておらず手法の検討もつきませんでした。
分かってしまえば「1つの PlayerController を前提に考える」だけで良かったのですが、調査をするなかでいろいろと学びもあり良かったです。



