UE4の勉強記録

UE4の勉強の記録です。個人用です。

「Unreal Engine4.xを使用してRPGを作成する」の足りない部分を作成する。Main Menu作成

<前文>

f:id:kazuhironagai77:20191020202935p:plain

先週、1週間かけて色々考えたり、調べたりしましたが、やっぱりRPGゲームを完成するまでをブログに書く事にしました。

色々な理由がありますが、最大の理由は、この本の続きを作成する事で、今までにない効果的なUE4の学習方法と言う、金脈を掘り出す事が可能と思えたからです。

この教科書には、私が今まで勉強したどのUE4の教科書やチュートリアルとも違い、ゲームの作成に必要なパーツの作成方法を教えています。

これをもう少し詳しく解説すると、

RPGには必要な骨格があります。型と言い換えてもいいと思います。例えば、

  • キャラクターが使用出来る装備や道具、
  • それらを購入もしくは売却できる店、
  • 更にそのキャラクターと会話出来るNPC
  • 戦闘
  • 戦闘に出て来るモンスター
  • HPやMPなどのキャラクターの職業やモンスターの種族に基づくパラメ―ター

です。これらはどんなRPGを作成するにしても必要です。この教科書ではこれらをパーツに分けてそれぞれのパーツの作成方法を教えています。

この方法は、考えてみると今まで私が勉強したUE4の教科書やチュートリアルでは、あまり取られていない学習方法でした。

今まで私が勉強したUE4の教科書やチュートリアルは、

  1. AをしてBをしてCをして...を延々と繰り返す。そして最期にゲームが完成するが、何も理解出来ない。
  2. UE4エディターの使用方法を教える。例えば、ブループリント、パーティカルシステム、アクタークラスなどの使用方法を教える。(UE4C++もこれに入ります。)これ自体は大切です。大切ですが、ゲームそのものの作成を全くした事がない初心者には、それぞれの分野をどれくらい勉強すればいいのかの判断がつかない。別な言い方をすれば、それぞれの使用方法をどんなに覚えてもゲームは完成しない。

のどちらか、もしくは両方を適度に混ぜ合わせた内容でした。

それに対して、この教科書は、

  1. RPGに最低限必要なパーツを明記して、それぞれの作成方法を教える。

と言う方法を取っています。最初私は、この方法が特別だとは考えませんでした。しかし、この方法を単に実行するだけで、今までどうしても理解出来なかった、ゲームにおけるソフトウェアデザインの一つであるコンパイルをする必要なしにキャラクターのパラメーターを変化させる方法が実装出来てしまいました。勿論、UE4を使用しているので、大半はブラックボックスです。ですが、この場合ブラックボックスでも何も問題ないです。ここで大切なのは、どんなRPGを作成するに当たっても、もっと大袈裟に言えばどんなゲームを作成する場合でも、コンパイルをする必要なしにキャラクターのパラメーターを変化させる事を実装する方法を学べた事です。

この成果は、1は論外としても2の学習方法でも得る事は出来ないと考えられます。つまり、この3の形式による学習方法は、特別な成果を学習者にもたらしてくれる可能性がある事が分かったのです。

ここから私はこの3の形式による学習方法に大変引き付けられました。この学習方法は、化学工学におけるUnit Operationの発明に匹敵する大発見だと思いました。

しかしそれを確認する事は出来ませんでした。

何故なら、この教科書はRPG作成に必要な全部のパーツの作成方法を網羅せずに、途中で終わってしまったからです。「こっから先は自分で作成してね。」と唐突にです。

もうこうなったら本当に残りを自力で作成するしかありません。

やってみます。

正し、時間制限をかける事にします。出来ない場合、見切りをつける必要があるからです。それは、UE4でカードゲームを作成するチュートリアルと、UE4ビジュアルノベルを作成するチュートリアルを既に見つけてあるので、そちらを学習する方が、3の学習方法の優位性を証明するのに速い可能性があるからです。まず1月までで一区切りとします。その時点で成果が出ているのなら続行しますが、ないのなら中止します。

<本文>

今回は、メインメニューを作成します。この教科書なぜか、メインメニューの作成がありませんでした。

今回は本当に最初の最初なので、手探りで始めていきます。

ブレインストーミング

兎に角、今頭の中にある事を全て書き出します。

メインメニューに必要な要素を以下に記します。

  • 絶対必要なのはロード機能です。スタートボタンに最初からとセーブデータからの二つの選択があり、更に理想を言えばセーブデータも3個ぐらいから選択出来るようにしたいです。
  • オプションボタンも必要です。音楽やFPSが調節出来るようにしたいです。

教科書の最後の最後で、ゴールドやキャラクターの装備などをセーブするBPの関数を習いました。SaveGameと言う名前でした。それを調べれば、データのセーブの仕方と、ロードの仕方のヒントが分かりそうです。

メインメニューはWidget Blueprintで作成しますが、最初からブループリントで作っていいのでしょうか?

教科書では、CombatUIブループリントは、最初にUE4C++で、UCombatUIWidgetクラスを作成してそれから派生させています。勿論、最初からWidget Blueprintで作成しているUIも沢山ありますが、UE4C++を使用するかしないかの違いは何なんでしょうか?

また、ネットにもUE4でメインメニューの作成方法を説明したチュートリアルがあるはずです。それらを参考にして作成して見るのもいいと思われます。

まとめます。

  1. メインメニューに必要な要素は、スタートボタン(最初からとセーブデータからの両方)、オプションボタンである。
  2. セーブしたデータから開始する方法は、今は分からない。SaveGameというBP関数を使用する事で出来そうなので、まずSaveGameBP関数について調べて見る。
  3. メインメニューは直接、ウィジェットBPから作成すべきなのか、それとも、UE4C++で作成したクラスからウィジェットBPを派生すべきなのか調べる。もしくは考える。
  4. UE4でメインメニューの作成方法を説明したチュートリアルがあるか調べる。あったら参考にする。

以上です。

<調査>

SaveGameBP関数について

まず、ネットでSaveGameの使用方法について調べました。

HTF do I? Use the SaveGame Object in Unreal Engine 4

Mathew Wadstein氏の解説で、簡単で非常に分かり易く説明されています。ただ、教科書の例と同じで、セーブしたデータが一個しかない場合で解説しています。

SaveGameの名前の欄を工夫すれば複数のセーブデータに対応した場合も何とか作れそうですが、何処かに、複数のセーブデータに対応したSaveGameノードの使用方法についての解説もありそうです。他のSaveGameの解説も見てみます。

Saving and Loading Your Game

公式のSaveGameの解説です。ブループリントとC++の両方で説明されています。C++のセーブ方法では、Asynchronous Saving、Synchronous Saving、そしてBinary Savingなどの今まで見た事がない用語が使用されてました。

SameGameの使用方法の解説はこれら以外にもありましたが、複数のセーブデータを保存する方法は載っていませんでした。自分で考えるしかなさそうです。

追加の情報としては、セーブした位置をセーブデータに保存する必要がある事と、どのデータを保存する必要があるのか完全に把握しておかないといけない事です。

ウィジェットBPからメインメニューを作成するか、UE4C++で作成したクラスから派生したウィジェットBPからメインメニューを作成すべきか?

実際メインメニューをUE4C++から作成するならどのように作成するのかを最初に調べます。

教科書のCombat UI with UMGにUE4C++からUIWidgetを作成する方法が逐一説明されています。この手順に従って作成すればUE4C++からUIWidgetそのものの作成は出来そうです。ただしこの教科書の例では、実装をブループリントで行う関数と、ソースファイルで行う関数の両方が紹介されています。変数に関していえば、この例で使用されている全ての変数は、UPROPERTYマクロを使用しない変数です。UE4C++でUIWidgetを作成しそこからBPを派生した場合、そのBPからUE4C++で宣言した変数を使用したいはずですが、それをどうすればいいかは調べないといけないみたいです。

一応、UE4C++からメインメニューの作成が出来ると仮定した場合、BPからメインメニューを作成すべきか、UE4C++でUIWidgetを作成しそこからBPを派生して作成すべきでしょうか?

私のUE4C++とBPの分担に関する考え方で、前々から述べていますが、デザイナーが変えていい部分は、BP、駄目な部分はUE4C++で書くのが最も作業効率が上がる。と考えています。

勿論、メインメニューの作成にも、デザイナーに変えて欲しくない部分はあるはずで、UE4C++でUIWidgetを作成しそこからBPを派生して作成したほうが良いと思います。

さらに、C++側でしか受け取れない何か(イベントや変数の値など)があるかもしれません。UE4C++でUIWidgetを作成しておいて損はしないはずです。

UE4C++からメインメニューの作成が出来るなら、UE4C++でUIWidgetを作成しそこからBPを派生して作成した方が、利点が多いと考えます。

チュートリアル調査結果

以下に示すメインメニュー作成のためのチュートリアルが見つかりました。もっと沢山ありましたが、見た目が格好いいのと、色々知らない事を教えてそうなサイトのみに絞って選びました。

  1. [UE4] Advanced Main Menu - Preview
  2. UE4 Menu Tutorial, Key Bindings, Video Settings Part 1 (Unreal Engine 4 Widget Blueprint)
  3. UE4 advanced tutorial: Main and options menu widget
  4. Tutorial - Blueprints MainMenu_PauseMenu - Unreal Engine 4

取りあえず、全部見てみます。

[UE4] Advanced Main Menu – Preview

これは、大変格好いいメインメニューだったのですが、マーケットで販売しているプラグインの解説でした。ので今回はパスします。

UE4 Menu Tutorial, Key Bindings, Video Settings Part 1 (Unreal Engine 4 Widget Blueprint)

これは、2時間もあるチュートリアルで、大変内容が高度です。流石に全部は見れないので、最初の1時間だけ2倍速で見ました。かなりデザイナー向けの内容になっていると思われます。アニメーション機能を駆使して非常に美しい映像を色々な個所に追加しています。デザイナーは絵だけかければ良いと思っていたのですが、この動画を見るとむしろ、デザイナーの方がUE4のいろいろな機能を使用出来ないと作品が作れないみたいですね。

見た部分のみからですが、ブループリントのみから作成しています。ホラーゲームを制作しているためかSaveGameは使用していません。

あまりブループリントのチュートリアルは見ないからかもしれませんが、かなりビビりました。こんなにすごいの作成しているのかと言う事と、デザイナー畑の人のようですがブループリントや他のUE4の機能をガンガン使用して、プログラマーが必要なく見えたからです。しかしビデオの途中でGaussian の関数か何かを使用する所で、この単語の読み方知らん。と言っていて我に返りました。ちょっと安心しました。

UE4 advanced tutorial: Main and options menu widget

見た目が凄いのと、オプションメニューで選択する項目が沢山あったので、視聴する候補に残しておいたのですが、全くしゃべらないで、ひたすら作業内容を写しているだけでした。

f:id:kazuhironagai77:20191020203306p:plain

ただし、このオプション画面はすごいです。最後にゲームの映像を流していましたが、非常にきれいでした。

2倍速でみたので完全には言い切れませんが、SaveGameは使用していなかったように思えます。後、ブループリントのみでした。

Tutorial - Blueprints MainMenu_PauseMenu - Unreal Engine 4 

基本的な部分を全部説明している感じでした。可もなく不可もなくと言う感じでした。今回作成するメインメニューはこのくらいでいいと思いました。Loadボタンはあったのですが、少なくとも私が2倍速で見た限りでは、作成していませんでした。後、ブループリントのみで作成しています。

大体、これらのチュートリアルで説明されているメインメニューの作成方法で十分な情報は得られたと思います。足りない部分は

  • SaveとLoadに関して。SaveGameの使用の仕方。
  • UE4C++からメインメニューを作成している例

の2点だけです。UE4C++からメインメニューを作成している例は見つかれば儲け物くらいに考えています。

SaveとLoadはそれに関するチュートリアルを探せばいいと思いました。

Saving and Loading Your Game

公式のサイトをもう一度、読み直したのですが、ここに書かれている内容だけでも複数のセーブデータの作成とそのロードは作成出来そうですね。

更にいくつかのビデオのチュートリアルを見たのですが、ビデオを一遍に見過ぎて、気持ち悪くなってしまいました。ここからは自分で考える事にします。

<ここまでのまとめ>

ここまでやって、気が付いたのですが、前回までは、料理のレシピ本を読んで、料理を実際にやってみるのと同じような事をしていました。

今回からは、そのレシピから作成し、更に、そのレシピを元に料理して、一定以上の味に仕上げなければならない。と言う事を行おうとしています。かなり大変です。

<もっといい方法を思いついた>

教科書でGame Overは作成しているので、同じ方法でメインメニューを作成するのは、どうでしょうか?

自分で全て行うと、とんでもレシピになってしまう可能性があります。だからと言って、いたずらにネットに上がっているチュートリアルをそのまま使用すると、日本料理のコースに突然、フランス料理が出てくるようなちぐはぐな形になりそうです。

ので、今回は妥協案として、GameOverメニューを真似て作成してみたらどうでしょうか。これならとんでもレシピになる可能性も少ないし、日本料理のコースに突然、フランス料理が出てくるようなちぐはぐさを生む事もなさそうです。

<ゲームオーバーメニュー作成の復習>

1. GameOverScreenウィジェットブループリントから作成します。

うーん。ゲームオーバー画面用のウィジェットはブループリントから直接作成してますね。メインメニューは、UE4C++でUIWidgetを作成し、それから派生したブループリントで作成したかったのですが。カレーライスを作るのに、カレーのルーから作成したらやり過ぎでしょう。そう言う事なのでしょうか?

今回は、妥協してこのGameOverScreenのやり方で行います。

2. ReStartボタンのOnClickに以下に示すコードをバインドします。

f:id:kazuhironagai77:20191020203422p:plain

この部分、教科書の説明と図が全然違っていたのを思い出しました。確かサンプルコードがこの方法で作成していたので、そのまま採用したはずです。このサンプルコードのやり方は教科書の説明と完全に一致してました。

ReStartGame()関数はRPGGameModeクラスで作成した関数みたいですね。BlueprintCallableをUFUNCTIONマクロで指定してBPから呼び出せるようにしたのでしょうか?確認してみます。

f:id:kazuhironagai77:20191020203442p:plain

あれ。そんな関数作成してないですね。元々あった関数なのでしょうか?

思いっきりUE4C++のAPIにありました。ReStartGame()関数のRemarkを以下に示します。

f:id:kazuhironagai77:20191020203501p:plain

GameMode.hファイルで宣言されていたので、UFUNCTIONマクロを念のため確認しましたが、普通にBlueprintCallableを使用してますね。

f:id:kazuhironagai77:20191020203521p:plain

因みにRestartGame()関数の実装部は以下の様になっていました。

f:id:kazuhironagai77:20191020203552p:plain

うーん。GameSessionクラスにある関数CanRestartGame()でゲームが再スタートできるか調べてるみたいですね。これが可能だと、次にMatchStateを調べるようです。このMatchStateはEnumなのでしょうか?

いや、RestartGame()関数がどのように作成されているかは、今知る必要はないですね。この辺で止めておきます。

3. マウスカーソルを表示させます。

以下に示すコードをBP内で組みました。

f:id:kazuhironagai77:20191020203702p:plain

マウスカーソルが表示されなければ、ボタンをクリック出来ないので当たり前ですね

4. hファイルに、変数、GameOverUIClassを宣言します。

f:id:kazuhironagai77:20191020203802p:plain

ここからUE4C++でコントロールする訳ですね。ワクワクしますね。ところでEditDefautlsOnlyはどういう意味でしたっけ。

UPROPERTYによると、

f:id:kazuhironagai77:20191020203822p:plain

とありますが、良く分かりませんね。

Unreal Engine 4 - UPROPERTY Explained [Breakdown Series]に非常に分かり易く説明されていました。

簡単にまとめますと、

まずEditAnywhere、EditInstanceOnly、そしてEditDefaultsOnlyは3つで一組だそうです。

このUE4C++からブループリントを派生した場合、その派生したBPクラスからのみ編集出来る場合は、EditDefaultsOnly。そのクラスから作成したそれぞれのインスタンスからのみ編集出来る場合は、EditInstanceOnly、そしてどちらからも編集出来る場合は、EditAnywhereで指定されているそうです。

このチュートリアル、見つけた時は、大変分かり易くて感激したのですが、作者が制作を止めてしまったみたいですね。残念です。

5. RPGGameInstanceのソースファイルに以下のコードを実装します。

f:id:kazuhironagai77:20191020203903p:plain

これは、Tick()関数内のCombatOverブーリアン変数がtrueになった場合に実装されていました。それはともかく、まずRPPGGameInstanceクラスのPrepareReset()関数を呼び出しています。この関数は教科書によると後で作成するそうなので、今はスキップします。

次が重要です。まずCreateWidget()関数を使用してUserWidgetを作成し、その後、AddViewport()で画面上に表示しています。

CreateWidget()関数から行きますが、2つ分からない所があります。

まず、最初のパラメーターであるGetGameInstance()です。この関数がGameInstanceを返すのは明らかですが、ブループリントからUserWidgetを作成した時にGameInstanceを使用しましたっけ。

Creating and Displaying UIから持ってきたイメージを下に示しますが、

f:id:kazuhironagai77:20191020203921p:plain

Owning Playerのパラメーターはありましたが、何も接続していませんね。私の記憶だと、GetPlayerControllerを繋いでいたような気がするですが。

次の疑問は、GameOverUIClassは初期化していませんよね。どこでアサイン(assign)するですかね。勿論、EditDefaultsOnlyと指定しているからUE4エディターから、何処かでするのでしょうが。

まあ、何とかなるでしょう。

6. GameInstanceクラスにPrepareReset関数を作成します。

メインメニューを作成する時に、使用しなければならないGameInstanceクラス内の関数はないはずなので無視して次に行きます。

7. DefaultRPGGameModeブループリント内で、GameOverUIClass変数にUserWidgetブループリントから作成したGameOverScreenを指定します。

f:id:kazuhironagai77:20191020204014p:plain

ここで初期化しているのですね。ふーん。

大体流れが分かりました。

<メインメニュー作成の案>

上記のGameOverの作成方法を真似て作ってみます。

  1. メインメニューをウィジェットブループリントから作成します。
  2. それぞれのボタンの機能をブループリントから作成します。
  3. マウスカーソルを表示させます。
  4. hファイルに、クラスUserWidgetから作成した変数、MainMenuUIClassを宣言します。
  5. RPGGameModeのソースファイルにメインメニューを表示させるコードを追加します。
  6. DefaultRPGGameModeブループリント内で、MainMenuUIClass変数にUserWidgetブループリントから作成したMainMenuScreenを指定します。

難しいのは5ですね。まずどの箇所で実装するかですが、BeginPlay()関数内が妥当ですかね。その後でGameInstanceをパスする事が良いのかの問題が出て来ますね。

後、2ですが、スタートボタンを押す前にキャラクターが動いたら大変ですので、キャラクターの操作を一時的に止める必要がありますね。これって出来るんでしょうか?もし出来なかったら今回はそのままにします。

<セーブとロードはどうするの?>

これも今、気が付いたのですが、まず3つのセーブデータがないんです。ので今回はロードの部分は空欄にしておきます。後で、セーブデータが出来てから考えます。

<メインメニューの作成>

1. メインメニューをウィジェットブループリントから作成します。

どんな感じに作成しますか?まずスタートボタン、オプションボタン、Quitボタンが必要ですね。さらにスタートボタンには、最初からとロードからが必要ですね。更にタイトルも必要です。このような絶対必要なウィジェットはUE4C++で設定してデザインのレベルから変更する事が出来ないようにしたかったのですが、今回は妥協してブループリントから作成します。

f:id:kazuhironagai77:20191020204128p:plain

MainMenuScreenと名付けました。

f:id:kazuhironagai77:20191020204147p:plain

取りあえずこれだけ作成しました。これがGame Modeから表示できなきゃこの計画は最初からやり直しになるからです。

所で、文字の外枠の色を変えて表示する事って前から出来ましたっけ。何か昔、外枠の色を変えようとして調べていたら、日本人と思われる人がそのものズバリの質問をしていてましたが、Epic Game社の人からそんな機能はないし、作る予定も全然ない。とにべもない断られ方をされていた記事を読んだような気がしますが。勘違いだったのかもしれません。

2. hファイルに、クラスUserWidgetから作成した変数、MainMenuUIClassを宣言します。

f:id:kazuhironagai77:20191020204220p:plain

作成しました。GameOverUIClass変数をそのままコピーしました。

3. RPGGameModeのソースファイルにメインメニューを表示させるコードを追加します。

BeginPlay関数内に作成してみます。

f:id:kazuhironagai77:20191020204254p:plain

こんな感じで実装してみました。これが上手く行けば、万々歳ですが行かなければ作戦を最初から考え直さなければなりません。時にGetGameInstance()の所が良く分かりませんので、どう直していいのかも分からなくなる可能性があります。

とりあえず、ビルドしてみます。

f:id:kazuhironagai77:20191020204311p:plain

ビルドは成功しましたね。

4. DefaultRPGGameModeブループリント内で、MainMenuUIClass変数にUserWidgetブループリントから作成したMainMenuScreenを指定します。

f:id:kazuhironagai77:20191020204343p:plain

しました。それではコンパイルしてテストします。

f:id:kazuhironagai77:20191020204410p:plain

出来ましたね。当たり前と言えばそうですが、それでもちょっとは感動しました。

5. MainMenuScreenにボタンなどの残りの機能を追加します。

f:id:kazuhironagai77:20191020204521p:plain

こんな感じに作ります。

今回は、スタートボタン、オプションボタン、そしてゲーム終了ボタンを追加するだけにします。

f:id:kazuhironagai77:20191020204541p:plain

スタートボタンを押すと上記の画面に切り替わります。最初からを押すとゲーム開始です。ロードするの機能はまだ作成していません。戻るを押すとメインメニューに戻ります。

終了を押すとゲームが終わります。

オプションを押すと以下に示すオプション画面に切り替わります。

f:id:kazuhironagai77:20191020204601p:plain

6. それぞれのボタンの機能をブループリントから作成します。

メインメニューが表示されている間は、キーボードからの操作が出来ないようにします。

f:id:kazuhironagai77:20191020204704p:plain

上記の方法で出来ました。

メインメニューを消してゲームを開始する時は、

f:id:kazuhironagai77:20191020204724p:plain

上記の方法で、キーボードからの操作が可能になるようにしました。

7. マウスカーソルを表示させます。

f:id:kazuhironagai77:20191020204801p:plain

いつものやり方で達成しました。

<まとめ>

今回は、メインメニューを作成しました。UE4C++から作成したメインメニューの作り方の例が見つからないので、教科書のゲームオーバースクリーンの作成方法を真似て、メインメニューの作成方法を確立しました。その手順に基づいて、実際にメインメニューをブループリントとUE4C++を用いて作成しました。

ロード機能については後日追加します。