はじめに
1ヶ月の締めくくりとして簡単な2Dゲームを作りたいと思っています。
前回昨日歩きまわれるステージができました。
次はタイトル画面とゲームオーバー画面がほしいところです。
クリア画面も作ろうと思いましたが今日は断念します。
しかし参照している動画がスコアやコイン、障害物の設置なども行っていますので
そちらも加えていきます。
ちなみに本日の最終成果物です
1. スコアを追加する
レベル(マップ)を1面と仮定します。私が今作っているものは1面しかありませんが。
1面だけなのでスコアもそのレベルで管理することもできると思いますが、レベルをまたがってゲーム全体でデータを管理するものがありますのでそちらを使ってみます。
それがGame instanceです。
1.1 Game Instance を追加し定義する
- ブループリントを作成。
- 名前: BP_GameInstance
- 親: Game instance
- プロジェクト設定より使用する Game Instance として上記を指定
- BP_GameInstanceをダブルクリックして編集モードに入る
- 変数を2つ追加
- 名前: Score 型: Integer
- 名前: Coin_Count 型:Integer
- 関数を追加
- 名前: AddScore
- インプットパラメータを追加
- 名前: AdditionalScore
- 型: Integer
- 関数の定義
- Score変数 をGetで配置(左端下段)
- Integer + Integer を配置
- Score変数 をSetで配置(右端)
- 図の通り接続
- 関数を追加
- 名前: CountCoin
- 名前: CountCoin
- 関数を定義
- CoinCount変数 をGetで配置(左端下段)
- Integer + Integer を配置
- CoinCount変数 をSetで配置(右端)
- 図の通り接続
- コンパイル & 保存
1.2 BP_Coin に得点とコイン枚数のカウントを加算用の処理を追加
- BP_Coin を開く
- Get Game instance を配置
- Cast To BP_GameInstance を配置
- ノード上で右クリックして純粋キャストに変更
- Cast To BP_GameInstance から関数呼び出し CountCoin と AddScoreを配置
- AdditionalScore の値は 100 としている
- AdditionalScore の値は 100 としている
- Play Sound 2d と Set FlipBook の間に上記ノード郡を挿入
- コンパイル&保存
1.3 WB_HUD の作成
ゲーム画面に得点と取得コイン枚数を表示させる為、HUD(Head Up Display)を作成する
- Blueprints フォルダでユーザーインタフェイス → ウィジェットブループリントを作成
- 名前: WB_HUD
- タブルクリックで編集画面に入る
- パネルからHorizontal Box を階層へドラッグする
- アンカーから上中央を選択する
- Horizontal Boxの設定
- 位置 x: 0
- 位置 y: 50 (上からの相対位置)
- Alignment x: 0.5 (中央からの相対位置で左に0.5ずらす)
- Size to Content: チェック (内容のサイズに合わせてサイズを決める)
- Horizontal Boxの中にVertical Box を追加
- Vertical Box の中に Textを追加し変更
- コンテンツ Text: Score
- アピアランス(見た目) の Size: 24
- Textを右クリック→複製、変更
- コンテンツ Text: 000000
- コンテンツ Text: 000000
- Vertical Boxを複製
- 上段のテキストのコンテンツ Text: Coin
- 下段のテキストのコンテンツ Text: 00
- 下段のテキストのJustification を中央揃えに設定
- 2つのVertical Boxの間にSpacerを追加し設定
- アピアランスx : 50
- アピアランスx : 50
- コンパイル & 保存
1.4 WB_HUD をゲーム画面に表示させる
- Blueprintsフォルダの2DSideScrollerGameModeを開く
- イベントグラフ上に BeginPlay を配置
- ウィジェットを作成を配置
- クラスを選択で WB_HUD を選択
- Add to Viewport を配置
- 接続
- コンパイル & 保存
- プレイして確認してみる
1.5 Coin取得時に画面上のコイン取得枚数の数を更新する
- WB_HUB のコインの数値部分を選択し、バインド → バインディングを作成をクリック
- 名前をGet Text 0 から Coin Bind とする
- Game Instance を配置
- Cast To BP_GameInstance を配置
- ノード上で右クリックして純粋キャストに変更
- Get Coin Count を配置
- Get Coin Count の Coin Count をReturn Value に接続すると To Text(Integer) が自動で配置される
- To Text(Integer)の▼をクリックして詳細を表示させ、Minumum Integer Digits を2にする。
- 最低でも2桁の0埋めした数字を表示させる事ができる。
- 最低でも2桁の0埋めした数字を表示させる事ができる。
- コンパイル & 保存
- プレイして確認してみる
1.6 Coin取得時に画面上のScoreの数を更新する
- WB_HUB のScoreの数値部分を選択し、バインド → バインディングを作成をクリック
- 名前をGet Text 0 から Score Bind とする
- Game Instance を配置
- Cast To BP_GameInstance を配置
- ノード上で右クリックして純粋キャストに変更
- Get Score Count を配置
- Get Coin Count の Coin Count をReturn Value に接続すると To Text(Integer) が自動で配置される
- To Text(Integer)の▼をクリックして詳細を表示させ、Minumum Integer Digits を6にする。
- 最低でも6桁の0埋めした数字を表示させる事ができる。
- Use Groupingのチェックを外す。チェックが入っていると3桁ごとにカンマが入る。例 1,000
- コンパイル & 保存
- プレイして確認してみる
– コインを取ると得点と取得枚数が加算されている事がわかる
2. あたったら死ぬ障害物を作成
可愛い女の子のキャラクターを使わせてもらっていて死んでしまうのは可愛そうなのでウンチにぶつかったらヘコむという設定にしていきたいと思います。
2.1 障害物の作成
Blender Sverchok を使って作成
- 成果物
2.2 インポート→スプライトの作成
2.3 効果音のダウンロード
- パニックパンプキンさんのサイトの効果音でモンスターぶよんとしたものをダウンロード
pansound.com - Sounds フォルダにインポート
2.4 自キャラクターにアニメーションを追加
自キャラにうなだれるというカスタムイベントを追加していきます
2.4.1 Flipbookの切り替えロジックを追加
- 2DSideScrollerCharacter を開く
- イベントグラフ Handle Animationの部分を修正
- dead (bool型)変数追加
- dead を Get で配置
- ブランチを配置して Dead の値に応じて分岐させる
- dead が True の場合は SetFlipbook でフリップブックを Dead に設定する
2.4.2 Dead変数を更新するロジックを追加
- カスタムイベントを追加
- 名前: Weep
- 変数dead を True にする Set ノードを配置
- Disable Movement で操作入力の受付を停止
- Set Actor Enable Collision で衝突の受付を停止
- Delay で 2秒間処理を遅らせる
- Open Level でマップを開いてリスタートする
2.5 BP_Obstacle を作成
コリジョンとメッシュをあわせてマップに配置でき衝突も管理できるものを作成してきます。
- Blueprint フォルダに新規ブループリントを作成
- 名前: BP_Obstacle
- 親: Actor
- ダブルクリックして編集モードに入る
- ビューポートタブに切り替え
- Paper Sprite コンポーネント追加
- Source Sprite は Unko を選択
- コリジョンプリセット: OverlapAll
- Box Collision コンポーネントを追加
- シェイプは Unko のサイズと重なるように調整
- コリジョンプリセット: OverlapAll
- イベントグラフに切り替え
- OnComponentBeginOverlapを追加
- ノードを追加
- Spawn Sound 2D で効果音を再生。ボリュームは 0.1 としている
- Cast To 2D SideScrollerCharacterを使って重なったキャラクターへキャスト
- キャストが成功した場合は Weep カスタムイベントを呼び出す
少し調整が必要に思いますができました。
3 ライフを減らす
ライフという概念を追加して。
障害物にぶつかったり、穴に落ちたら減らします
3.1 ライフを追加
- BP_GameInstance を開き Life という変数を追加
- デフォルト値は変数追加後にコンパイルをすることで表示される
- MinusLife という関数を追加
- コンパイル & 保存
- WB_HUD を開く
- 手順 1.3 WB_HUD を参照し Life という表示項目を追加
- 1.5 Coin取得時に画面上のコイン取得枚数の数を更新するを参照し Life Bind という関数を追加
- コンパイル & 保存
3.2 障害物衝突時にライフを減らす処理を追加
- 2DSideScrollerCharacter を開く
- Weepカスタムイベントのdelay と Open Level 間にノードを追加
- Get Game Instance で Game Instance を取得
- Cast To BP_GameInstance で BP_GameInstance にキャスト
- キャストした中から MinusLife を呼び出してLifeを-1する
- コンパイル & 保存
3.3 穴に落ちた際にライフを減らす処理を追加
- レベルブループリントを開く
- KillZVolume Overlap時のイベントを修正する
- コンパイル & 保存
4 ゲームオーバー画面を追加
ライフが0未満になるとゲームオーバーになるようにします。
しかし残りのライフの数は Game Instance(ゲーム全体)で管理するのはわかりますが、ゲームオーバーかどうかをチェックするのはどこでやればいいのでしょうか?これもGame Instanceな気がしますが、今回は参照元にならって Game Modeで管理します。そのためには今まで作ったものをいくつか修正する必要がありますので合わせて行います。
4.1 WB_Instance MinusLifeの関数を引いた後の数を返すように変更
- BP_GameInstance を開く
- MinusLife関数にリターンを追加
- GameOver という変数を追加
- デフォルトで False なのでそのままにしておく
- デフォルトで False なのでそのままにしておく
4.2 Game Over画面を追加
- WB_HUDを開く
- Text を追加し修正
- アンカーを画面中央
- Alignment XY: 0.5
- Size To Content: チェック
- Text: GAME OVER
- Size: 157
- ビヘイビアのVisibilityをHiddenにして、バインディングを作成をクリック
- ノードを設定
- 名前を GameOver? とした
- リターンノードの Return Value をドラッグして「選択する」を配置
- BP_GameInstance のGameove変数を接続
- ゲームオーバー画像も設定
4.3 2DSideScrollerGameMode側の修正
- 2DSideScrollerGameMode を開く
- Custom Event を配置して名前をLife Lostとする
- Minus Lifeを呼び出し結果が0未満かどうかを確認
- 0未満であれば Game Over カスタムイベンをへ処理を渡す
- 0以上であれば Open Level でマップを開く
- Custom Event を配置して名前をGame Overとする
- Gameoverフラグを True にする
- Trueにすると直ちに画面にGameOverが現れる
- Delay秒待つ
- OpenLevelでマップを開く
- Gameoverフラグを True にする
4.4 BeginPlay時、CharacterにGameModeへの参照を取得しWeep時のイベントを修正
- 2DSideScrollerCharacter を開く
- Game Mode 変数を追加
- Begin Play にゲームモード取得用の処理を追加
- Weep の処理を変更する
- Delay 以降を削除して GameModeから LifeLostを呼び出すように変更
- コンパイル & 保存
4.5 BeginPlay時、レベルにGameModeへの参照を取得し穴に落ちた際のイベントを修正
- レベルブループリントを開く
- BeginPlayに 4.1 と同様の処理を追加する
- OnActorBeginOverlap(KillZVolume)
これでライフが0の時にライフを失うとGameOverと画面上に表示が出るようになったが、依然として表示が出たまま何事もなかったかのようにゲームは続行する。
ゲームタイトル画面を追加しそちらに移行するようにする
5 ゲームタイトル画面を作成する
5.1 Title用のウィジェットBPを作成
- ウィジェットブループリントを作成
- 適当に編集
- ボタンの透明度を設定
- ボタンの透明度を設定
- プレイを押したときのイベントを作成するため、イベント On Click の + を押す
- OnClick に対するイベントをノードで設定
- デザイナーモードに移り、止めるボタンに対するアクションを定義するため「止める」ボタンを選択、イベントの + を押す
- OnClickに対するイベントをノードで設定
5.2 Title用のレベルを作成
- レベルを新規作成し Title という名前にする
- Titleを開く
- レベルブループリントを開く
- Title のイベントグラフが開けている事
- Title のイベントグラフが開けている事
- BeginPlay ノードを設定する
- ウィジェットを作成ノードでは WB_TITLE が選ばれている事
- ウィジェットを作成ノードでは WB_TITLE が選ばれている事
- コンパイル & 保存
5.3 最初に開かれるレベルをTitleに設定する
- ツールバーよりプロジェクト設定を開く
- マップ&モードの 「ゲームのデフォルトマップ」を Title マップに設定する
5.4 GameModeのGameoverイベントを修正
- ノード最後のOpenLevel をTitleにする
最後に
本日の最終結果。タイトル→ゲーム→ゲームオーバー
一応手順をまとめながら行っているが実際に行った手順は前後しまくっていて、それを後で行ったり来たりしなくて良いように一本道の手順でいけるように並び替えている。
なれてきたら一本道で行けるのでしょうが、まだまだ何をしなければ行けないのか理解できておらず断片的な知識でやっているから行ったり来たりするのでしょうね。
早く慣れたいものですが、ブログに書くことは確実に早く慣れる一歩でしょう😄
メモ
- イベントグラフ上で P + クリックで BeginPlayイベントノードを配置する
ゲームの一連の流れと必要なアセット
ステージ | レベル | ゲームモード | ウィジェットUI | 備考 |
---|---|---|---|---|
タイトル | ○ | ○ | ○ | |
ゲーム | ○ | ○ | ○ | |
ゲームオーバー | – | – | △ | ゲーム中と同じウィジェットを使用 |
- レベルはリザルト画面や別のステージ、ゲームオーバーなどシーンが別れた場面で分けられる事が多い
スプライト(Sprite)とは?
テクスチャ マッピングされる平面的なメッシュ
docs.unrealengine.com
音楽素材
- パニックパンプキンさん
pansound.com
英語メモ
- HUD Head Up Display
ヘッドアップディスプレイ(英語: Head-Up Display、略称: HUD、「ハッド」と発音する)は、人間の視野に直接情報を映し出す手段である。この技術は軍事航空分野において開発され、実験的にではあるがさまざまな分野に応用されている。Wikipedia
接頭辞
- WB_ Widget Blurpint
その他
素材
https://gist.github.com/0679031a6987b712d9c38667b4b8630c
Puml
@startuml title Relationships - Class Diagram class Game { +Levels } class 2DGame class GameInstance class GameState class Level Game <|-down- 2DGame: Inheritance Game "1" *-- "1..*" Level Level "1" -- "1" GameMode Game "1" *-- "1" GameInstance Game "1" *-- "1" GameState @enduml