スタート時のキャラクターを選べるようにする
前回、メニューを出してキャラクターを変えられるようにしましたが、
ゲームスタート時にも使うキャラクターを選べる画面を作りました。
https://qiita.com/KLaboratory/items/af3c63d7db4a0ccaaff7
それに伴い、スタート画面用のレベルと、メニューのウィジェット
メインレベルを作りました。
また、グローバル変数を格納するゲームインスタンスを作りました。
ゲームインスタンス
2つの変数を作ります。最初はActorクラスの配列。
デフォルト値に使用するキャラクターを入れます。今回は3つ用意しました。
もう一つは、配列のインデックスを取得する整数。デフォルト値は0。
ゲームインスタンスはこれだけです。
これをプロジェクト設定のゲームインスタンスに設定します。
スタート画面(ウィジェットBP)
スタート画面用のウィジェットブループリントを新規で作ります。
何も選択せずにスタートボタンをクリックすると、DefaultPawnの
が選ばれます。イベントグラフは簡単です。ゲームインスタンスのインデックスをセットするだけ。
これでゲームスタート時に使うキャラクターが決まります。
スタートボタンをクリックしたときにメインレベルを開き、
Quitボタンをクリックするとゲームが終了します。
スタートレベル
スタートレベルを作ります。新規レベルでデフォルトを選んで作成したあと、すべてのActorを削除します。
なにもActorがないので、専用のゲームモードを作ります。
ブループリントには何も必要ありません。DefaultPawnClassをNoneにします。
スタートレベルのワールドセッティングをこのゲームモードにします。
※GameMode Overrideを「None」にしても今回は同じ挙動になります。
※ただ、他にもNoPawnのレベルを作るならばゲームモードを用意しておいたほうがいいと思います。
続いて、スタートレベルのブループリントですが、
ウィジェットを開いてカーソルを見えるようにするだけです。
メインレベル
ワールドセッティングは今までのゲームモードを設定します。
レベルブループリントは以下のとおりです。
前半部分、ゲームインスタンスに記録されたインデックスが0以外になっていると、
デフォルトキャラクター以外が選択されたことになります。それを取得します。
後半は、デフォルトキャラクターをDestroyして、選ばれたキャラクターをspawnします。
これは今までの応用です。アクターの配列からインデックスを指定することで、
Spawnするキャラクターが決まります。
ただ、今まではそのままPossessに接続できましたが、一旦キャラクターにキャストする必要があります。
ゲーム途中のキャラクターを変える
3つ以上のキャラクターから選ぶ
前回までは2つのキャラクタを交互に替えていただけですが、
3つ以上のキャラクターを選べるようにしました。
キャラクターチェンジ画面(ウィジェットBP)
キャラクタチェンジ用ウィジェットブループリントを新規で作ります。
スタート画面と同じ要領ですが、背景は透明にして、Start、Quitボタンはありません。
続いてブループリントです。
前半はスタートウィジェットと同じく、ゲームインスタンスのインデックスをセットします。問題は後半
RemoveFromParentで、画面を消します。続いてSetInputModeGameOnlyでインプットはゲームのみで有効にします。
マウスカーソルを非表示にして、最後にイベントディスパッチャーを発行します。
これがないとうまくいきませんでした。詳しくはPlayerControllerで説明します。
PlayerController
今までの変身に加えたのですが、相当長い処理になりました。
変身のコマンドが入力された瞬間、現在のキャラクターのインデックスを取得し、ローカル変数に格納します。
続いてウィジェットとマウスカーソルを表示させます。
SetInputModeUIOnlyはウィジェット画面だけインプットが有効になるための処理です。
なので、先程のウィジェット消去画面で、ゲームにインプットを戻す必要があるのです。
SetGamePausedでゲームを止めます。そうしないと、メニュー選択の間にもゲームが動いてしまいます。
つづいて、ウィジェットから発行されたイベントディスパッチャーをバインドします。
カスタムイベントでイベントディスパッチャーからのイベントを受けます。
SetGamePausedでゲームを止まっているゲームを再開します。
メニュー画面が出た瞬間と、消えた瞬間でゲームインスタンスのインデックスの数字が
替わっていたら、キャラクターが替わっているので先に進みます。
同じキャラクターを選んだ(替えるのをやめた)場合は何もしません。
アクターをDestroyして、新たにSpawnActorをします。今回はスタート時のキャラクターが
どれかわからないので、0(デフォルト)であるかどうかを判定する必要はありません。
イベントディスパッチャーを何故入れるか
実は私も理由がまだわからず教えて欲しいところでもあります。ただ、こうしないと、
画面が止まったまま、キャラクターだけが入れ替わる
ということになります。SetGamePausedは入力や画面は止まるけど、
内部の処理は止まらないのではないでしょうかね?それをイベントディスパッチャーでせき止める。
そんなイメージではないかと思っていますが、ご存じの方がいらっしゃったら教えて下さい。
キャラクターセレクトメニューを作る。#UE4 #UnrealEngine4 pic.twitter.com/Y4TpXKPWW7
— 特命社長 (@tokumeishatyo) May 17, 2020