【UE5】移動してゴールするだけの簡単なステージを作ってみよう
こちらの記事で、とりあえず一通りのゲームの体裁(タイトル画面→キャラが移動するステージに遷移→ゴールする→エンドロールが流れる)が整うところまで試しに作ってみようということになりました。
前回の記事にて、タイトル画面までは作成してみました。
今回は、タイトル画面から遷移する先のオリジナルの簡単なステージを作ってみようと思います。
新しくレベルとステージの土台を作る
さっそくですがステージを創っていきます。サンプルを使うままだと味気がないので、少し頑張ってオリジナルのステージを創っていきます。
3Dアセットをマーケットプレイスから入手
ゼロからアセット(3Dモデルなどの素材)を用意するのは大変なので、今回は3DWORLD – Japan Modular Cityという、日本の都市を再現したローポリ3Dモデルの有料アセットを使ってみました。
3Dアセットを自分のプロジェクトにインポート
マーケットプレイスでアセットを購入すると、Epic GamesアプリのUnreal Engine > ライブラリ > マイダウンロードにアセットが表示されています。
対象のアセットのところにある「プロジェクトに追加する」ボタンを押すと、自分のUEプロジェクトに追加してアセットを使えるようになります。
追加が終わると、こんな風にコンテンツフォルダ直下にJAPAN_ModularCityというフォルダができて、そこの中にあるアセットを使えるようになります。
新しいレベルを作成
以前の記事にあったチュートリアルでもやってきたように、新しいレベルを作成します。
「ファイル>新規レベル>空のレベル」を選択し、そのあとすぐに「ファイル>現行レベルを名前を付けて保存」を選択します。今回の名前はstage01にしました。
最初は何にもありません
アセットを配置してステージっぽくする
素材を置いて、それっぽいステージを創っていきます。
まずは光がないといけないので、ライト>ディレクショナルライトをとにかく配置。
あとはJAPAN_ModularCity>StaticMeshesにある素材をドラッグアンドドロップ&微調整で道路を敷いて、車なり見せなりを置いてそれっぽいステージにします。
ざっと仮ですが下の絵のようなステージを作ってみました。右の「スタート」の三角コーンがあるところからスタートして、浮いている車の上を飛び移りながら、「ゴール」のゲートまで目指すステージです。
1つステージのゴールを設定したく、こちらのアセットを持ってきました。
スタートからゴールまで走らせてみる動画(判定なし)
まだゴール判定などは設定していないので、そんなにゲーム性はまだないですが、とりあえずスタートからゴールまで走っていくところまで遊べます。
ステージから一定以上の高さまで落下したらタイトルメニューに戻るようにする
現状では、ステージの端には柵も何もおいていないので、端から落ちるとそのままずっと落下し続けてしまいます。
一定以上落下したらゲームオーバーにするようにしてみます。
下記のリンク先のようなサイトを参考にさせていただきました。
キルZを設定する
キルZとは、この値以上になると「ゲームオーバー」となる判定のパラメータです。
「ワールドセッティング>ワールド」に設定項目があります。デフォルト値は-1048575.0とかなり大きい値になっています。
これを例えば-5000くらいにしてみて、落下するとどうなるか見てみると、下の動画のようになります。
キャラクターがキルされた後の処理を設定(ダメなやり方)
現状、一定値以上落下した後、キャラクターが消えますが、それでゲームが固まって終わりになってしまいます。キャラクターがキルされたところまでは設定できていますが、キルされたあとどうするかは設定されていない状況です。
そこで、キャラクター(アクタ)が破壊(キル)されたら、メインメニューに戻るように設定してみます。
キャラクターは、現在BP_ThirdPersonCharacterというブループリントで管理されていますので、これを開いてイベントグラフを編集してみます。
イベントグラフを開いて、空の部bンでEvent Destroyedを追加し、その先のシーケンスにOpen Level(by Name)を置く。Open Level(by Name)のパラメータのLevel Nameに、「MainMenuLevel」を記入。これでキャラクターがDestroyされたときに、メインメニューに移動する・・・はず。
しかし、これだけだと実は問題があります。
キャラクターが死んだあと、メインメニューに戻るのですが、再度メインメニューからゲームを始めようとしてゲームステージに戻っても、キャラクターが死んだままになっているので、すぐメインメニューに戻されてしまいます。
代わりに、キャラクターが死んだときに、レベル遷移すると同時に、キャラクターを再度初期位置に生まれさせる(リスポーンさせる)必要があります。
キャラクターがキルされた後の処理を設定(適切なやり方)
キルされた後の処理をうまく書くために、BP_ThirdPersonCharacterのほうだけでなく、BP_ThirdPersonGameModeにも手を加えます。この2つのブループリントは一見わかりにくいのですが、整理すると下記のとおりです。
BP_ThirdPersonGameMode:
- ゲーム全体のルールとロジックを管理。
- ゲームの進行や状態、リスポーン、HUDなどを設定。
BP_ThirdPersonCharacter:
- プレイヤーが操作するキャラクターのロジックを管理。
- キャラクターの動き、アニメーション、入力処理、属性、アクションなどを設定。
リスポーンなどのゲーム進行にかかわる処理はゲームモードに実装したほうがよく、キャラクターの死などはCharacterのBPでハンドリングしてGameModeに渡すのが良いようです。
今回、全体の流れは次のようになるようブループリントを創りました。
- BP_ThirdPersonGameMode側にて、レベル起動時にPlayer Startの初期位置を記録。
- Event Begin Playイベントを受けて、Get Actor ClassによりPlayer Startの情報を取得するようにノードを用意。そのノードからGet Actor TransformでPlayer Startの位置姿勢(Transform型)を、新規作成したSpawn Transformという変数に格納
- BP_ThirdPersonCharacter側にて、プレイヤーがキルZの判定で破壊(Destroy)されたことをトリガーにして、BP_ThirdPersonGameMode側を呼び出して(Cast)、Respawn Playerというカスタムイベントを呼び出す
- Event Destroyedイベントから、Cast to BP_ThirdPersonGameModeノードをつなぎ、その先にRespawn Player関数実行のノードを置く。
- BP_ThirdPersonGameMode側にて、Respawn Player関数が実行されて、プレイヤーを初期化して0.1秒後、キャラクターをリスポーンさせる。リスポーンさせた直後、メインメニューにレベルを遷移。
- Respawn Playerというカスタムイベントを用意
- Respawn PlayerイベントからDestroy Actorというノードを呼び出してキャラクターを破壊、Delayで0.1秒待った後、Spawn Actor を実行。Spawn Actorの先にOpen Level (by Name)を用いてMain Menuにレベルを遷移。
上記の流れを実現するブループリントは下図の通り。
- Get Actor Of Classを何度も呼ぶと有効ではない返り値が来る時があるので、is validとbranchを挟んで処理
- 変数としてSpawn Transformを宣言して利用
- RespawnPlayerイベントには、BP ThirdPersonCharacter型のインプットを用意
キル後の処理を適切に行った結果動画
無事落下した後、タイトルメニューに戻れるし、タイトルメニューに戻った後に初期位置に戻ってくれている。
タイトル画面でのマウスカーソル有効化
3Dのゲームステージからタイトル画面にレベル遷移すると、マウスカーソル表示が消えたままになっていることがある。
これを防ぐべく、タイトル画面のレベルブループリントには、下図のようにマウスカーソル有効化の処理をいれておくとよい。
エンドロールを作成
エンドロールはほぼタイトル画面作成と同じなので、説明は割愛。こちらをご参照ください。
こんな見た目で作りました。
次のゴール作成で使います。
ゴールを作成
次にゲームの要、ゴールを作ってみます。
下記記事を参考にしました。
ゴールのブループリントを作成
コンテンツブラウザに行き、新しいブループリントクラスを作成します(右クリック>ブループリントクラス>アクタ)。名前はBP_Goalにします。
作成したBP_Goalをダブルクリックで開きます。
左上のコンポーネントペインで、+追加>スタティックメッシュコンポーネントを指定。
今回ゴールに使っているS_Japanese_Wooden_Well_Roof_ui2jbif_lod3を右側のペインにあるスタティックメッシュに指定(コンテンツブラウザからドラッグアンドドロップすると楽)。サイズも調整(今回はサイズ10倍)。
さらに衝突判定用の球(Sphere Collision)を追加します。同様にサイズ調整。
右側の詳細ペインの中>イベント>On Component Begin Overlapの隣にある+をクリックすると、イベントグラフが起動し、この球にキャラクターが衝突したときのイベントを処理できるようになります。
このイベントグラフで、下記を実行できるように編集します。
- エンドロールへのレベル遷移
- エンドロールに行く前に、キャラクターの位置を初期化。
- これを実行しないと、エンドロール>タイトルメインメニュー>ゲームをはじめると進んで再度3Dゲーム空間に来た時、キャラクターが初期位置にいないことになり成立しない。
- ゴールした時のイベントをBP_ThirdPersonCharacterで定義し(Event Goal)、先の工程で使用したRespawn Playerイベントを呼ぶ。
- ただし、今のままだとRespawn Playerイベント発生時にプレイヤーをDestroy Actorを呼ぶ仕様になっているので、ゴールした後にEventDestroyedも同時に呼ばれてしまう。また、Respawn Player側にレベル遷移の記述がある状況。そこで、Respawn Playerイベントにもう1つ「ゴールしたかどうか」を示すGoal Flagを追加し、条件分岐するようにする。
- Goal FlagがTrueならエンドロールへ、Falseならタイトルメインメニューに戻るようにレベル遷移を設定。
- BP_ThirdPersonCharacter側でも、Goal Eventが走った際にはローカル変数のGoal FlagがTrueになるようにして、Event Destroyedの際にRespawn Playerが二重で走らないように対応。
ざっとブループリントにするとこのようになります。ちょっと複雑になりました。
完成
上記一通りの実装を入れた結果動画がこちらです。
ゲームタイトル→ゲームステージ→ゴール→エンドロール→タイトルメニューという、ゲームの体裁を整えるところまでできました。
ちょっと雰囲気出すために暗くしました。
まとめ
一通り、ゲームを創るうえで最低限必要なラインまでの知識をさらうことができました。
ここから、本格的に面白さを兼ね備えたゲームを作成していきたく思います。
「大人の階段」というホラーゲームは、今回の遊びで作ったステージではなく、きちんと怖めのストーリーを考えていて、ちゃんとホラーゲームとして作るつもりなので、できるまでどうかお待ちください。