<前文>
Fall Guysを見て思った事
正直、私でも作れそうと思いました。しかし同時に私にはこのゲームを発想する事は出来ないとも思いました。このゲームの肝はゲーム内で障害物競争を多人数でしたら面白いはずと言うアイデアと、水平に進む事で正解に近づき、垂直に落ちる事で失敗した事に気付くという人間の本能に直結したゲーム内容です。これは思いつかないです。
しかし世の中にはFall Guysのような面白いゲームを発想出来る人もきっといるはずです。これからはそういうアイデアを持った個人が開発したゲームがAAAの何百億とかけたゲームより売れる時代が来るんでしょうね。そして先週も書きましたが日本文化は世界の中で非常に独特で、そういうアイデアが生まれやすい土壌があると思っています。この日本からゲーム一本で何百億も稼ぐ人が出てくると思います。
そう考えるとこれからの時代はゲームを作って一発当てる人生もアリかも知れません。
ゲーム好きな人は潜在的な頭の良さはピカイチだったのに、学校の勉強を全くしないで人生のレールから外れてしまった人が多いと聞きます。そういう人たちは敢えてゲームを作って一発狙った方が色んな意味で豊かな人生が歩めるじゃないでしょうか。確かにゲームエンジンを使用してゲームの制作が出来る様になるのは決して簡単ではないです。Computer Scienceの分野ではトップレベルのアメリカの大学を卒業した(卒業論文は査読付きの雑誌に掲載された)私でも正直難しいと思います。
しかし元々頭が良い人が正しい方法で勉強すれば理解出来ないレベルの難しさではないと思います。ここで大切なのは正しい方法で教える教材です。UE4に限りませんが、ゲームエンジンの使用方法やゲーム制作を教える教材は、日本語英語に限らず、それで勉強してもゲームを作れるまでには理解が深まる事はないものが多いです。
英語の勉強に例えると分かり易いですが、単語ばっかし覚えてる人がいたとします。そういう人が生の英語を聞くと一字も聞き取れなくて、英語難しい、俺には一生英語を話せるのは無理。と勘違いしてしまいます。しかし本当は、生の英語を聞き取る為には別な勉強が必要なだけです。英語をしゃべったり書いたり出来る様になるためにも別な勉強が必要です。これらの事を総合的に学べば3カ月もすればそれなりに英語で考えれるようになって、聞いたり、書いたり、しゃべったりがそれなりですが出来る様になります。
そういう人達向けにUE4の使い方を教える講座とか作ったら売れるかもしれませんね。
それでは今週の勉強を始めます。
<本文>
今週も、programming partとdesign partに分けてやって行きます。
Programming part
先週、途中で終わった戦闘中のアイテムの使用の機能を完成させます。
Design part
村の作成を続けます。
1. Programming Parts
1.1 AttackTarget()関数の見直し
先週、アイテムを使用した際にこの関数を呼ばなかったから戦闘の途中で動作が止まってしまいました。
今回はこの関数の機能から調べていきます。
まず、TestCombatAction()を作成しています。
あれ、この作成されたTestCombatActionのBeginExecuteAction()関数を見てみると、敵に(自分の攻撃力‐敵の防御力)のダメージを与えているだけですね。
普通に攻撃した場合はこれでいいですが、魔法やItemを使用した場合は困りますね。
確か教科書に特殊攻撃をした場合の例が載っていたはずです。それを見てみましょう。
教科書の10章の6節Abilities logicを読み直すと、
単に攻撃力を2倍に設定して攻撃が終わったら元に戻しているだけのようです。
しかし本来ならばこれはItem専用のTestCombatActionクラスを作成して、それを使用すべきなはずです。
のでそうしましょう。
1.2 Item専用のTestCombatActionクラスの作成
1.2.1 Item専用のTestCombatActionクラスを呼び出す関数をCombatUIWidgetクラスに作成する。
まず、CombatUIWidgetクラスにUseItemInCombat()関数を追加しました。この関数がItemのためのTestCombatActionを呼び出します。
このCombatUIWidgetクラスからBPクラス
が作成されています。UE4C++のコードを変えるとその派生のBPに問題が起きる時があったので、今回はしっかり確認します。
まずbuildします。
これは問題ありませんでした。
しかしCombatUIからこの新しく作成した関数、UseItemInCombat()を呼び出そうとしたら出来ません。
うーん。何で?
念のためUE4 editor側からCompileしたら
今度は出て来ました。
うーん。良く分からないですが、これ以外は特に問題なかったです。
1.2.2 UseItemInCombat()をBPから使用する。
以下に示したのが、AttackTarget()関数を呼び出しているBPで攻撃の対象を選択した時に実行されます。
これ見るとAttackTargetを選択してActionPanelを隠してコメントを表示する事しかしていません。
今度は私が先週作成したItemを選択し、対象となるキャラを選択した時のコードです。
ここで全部実行していました。これは間違っていましたね。ここですべき事は、
- AttackTargetを選択して
- ActionPanelを隠して
- コメントを表示する
の3つだけです。これも直す必要がありますね。
取りあえず、以下のように変更しました。
AttackTargetはそのまま使用していますが、対象となるキャラが自分の場合もあるのでこの辺からテストしてみます。
あれ。これでも戦闘の途中で終わってしまいます。
一時間以上かかりましたがとうとう原因らしきものを見つけました。以下の部分でItemやRunを選択した時に次のノードを実行する事なく終了しています。
以下のように直しました。
取りあえず次のノードの繋いで試してみます。
今度は最後までいきました。
ああ。びっくりしました。ずっとCombat engineのコードを追っていました。こんな簡単な所を見落としていたとは。
それでは、本来の目的のUseItemInCombat()関数をAttackTarget()関数の代わりに使用します。
といっても中身の実装を全く作成していないので中身はAttackTarget()関数をそのままコピーしました。
AttackTarget()関数の代わりにUseItemInCombat()関数を使用します。
普通に動きました。
ついでに使用したアイテムを保持しているitemから消します。
あれ、道具が全部消えています。
これRemove()関数を使用したら一個だけ消えるから…と言う事で前に直したヤツをそのまま使用しているんですが、直した時に間違えたみたいですね。
ブログを見直したら、8月2日のブログで間違った方法で直していました。
成程、ThirdPersonCharacterクラスのtext配列からGameInstanceクラスのFStringのTArrayに変更したからRemove()が所持しているitemから一つだけ消去すると勘違いしたみたいですね。Removeは一種類のアイテムを全て消去するので、テストした時にそれぞれの種類のアイテムを一つだけ所持していて気が付かなかったみたいですね。
こっちに戻す必要がありますね。これをまず直してしまいましょう。
1.2.3 Itemの消費バグの直し
直しました。
テストします。
ダークイーサーを3個購入して戦闘で一つ使用しました。
出来ているみたいですね。
ついでに通常のItem使用の場合も直しておきます。
テストします。
回復薬が3つあります。一個使用します。
一回Pause画面を閉じて開き直しました。
回復薬が一個減っています。出来ているようです。
1.2.4 Item専用のTestCombatActionクラスの作成
時間がかかってしまいましたが今度こそ、Item専用のTestCombatActionクラスを作成します。
前どうやって作成したのか忘れてしまいました。のでこれで作成します。
まず、動くのかの確認が必要なので実装部はTestCombatActionクラスと全く同じにします。
そしてCombatUIWidgetクラスからTestCombatActionItemを作成します。
これでTestCombatActionクラスを使用した場合と全く同じに動くはずです。
試してみます。
問題なく戦闘中にItemを使用できました。
使用したitemは無くなっています。
1.2.5 TestCombatActionItemの改良
取りあえず以下のように改良しました。
これでBeginExecuteAction()関数を呼ぶ前にSetItemProperty()を呼べば、Itemが変化させるMP値とHP値をTestCombatActionItemクラスにパスする事が出来ます。
それを踏まえて、UCombatUIWidgetクラスの関数を以下のように改良しました。
これで使用したアイテム分のHPとMPがターゲットに追加されるはずです。
テストしてみます。
先ず戦闘開始前のそれぞれのHPとMPは以下の通りです。
KUMOにダークイーサーを使用します。
KUMOはゴブリンに攻撃され、更に自分が使用したダークイーサーの作用でHPが10減り、MPが20減るはずです。
その通りの結果になりました。
今度は、イーサーをKUMOに使用してみます。
KUMOはゴブリンに攻撃され、更にHPが10減りますが、使用したイーサーの作用で、MPが20増えるはずです。
その通りの結果です。
こんどはKUROに回復薬を使用します。
回復薬を使用したのでHPが100まで回復したのですが、その後にゴブリンに攻撃されたので10下がって90になりました。
この後、ゴブリンに回復薬が効くのか試したかったのですが、KUMOが攻撃したら一撃で死んでしまいました。
のでゴブリンの種族値をいじってHPを100にしました。いかに一回KUMOが攻撃した後の図を示します。
ゴブリンに回復薬を使用します。
ゴブリンのHPが20回復しました。
一応出来ていますね。
1.3 戦闘時のitem使用におけるコメントの直し
アイテムを使用した時のコメントがおかしいのでそれを直します。
まず、最初の部分だけ直しました。
道具を選択したら、道具、選択した道具の名前、そして使用する相手が表示されます。
以下に追加したコードを示します。
CombatUIで道具ボタンをクリックした時に実行されるコードです。
CombatItemウィジェットの道具の一つ(例えば回復薬)を選択した時に実行されるコードを以下に示します。
TargetCharacterウィジェット内でitemを使用する相手を選択した時に実行されるコードです。
それと大変なバグを一個見つけました。
攻撃ボタンを押した後、更に道具ボタンを押せます。そうすると以下に示したようなコメントが表示されてしまいます。
後で直します。
次のコメントは以下のように表示されています。
これが攻撃を選択した場合は、
となっています。
まず、“KUMO”がゴブリンを攻撃しました。に当たる文章が表示出来る様にします。
結果から示すと以下のような文章を表示するように出来ました。
以下にコードを示します。
CombatItemウィジェットに追加した部分です。
TargetCharacterウィジェットに追加した部分です。
最後に以下の部分を直します。
先程作成したTestCombatActionItemクラスのBeginExecuteAction()関数内で実行される以下の関数がこの部分のコメントに関わっています。
のでC++の挙動にも注意しながら直していきます。
まず、ReportDamageHPtoRPGGameModeBase()関数は以下に示したように、GameCharacterクラスの関数で、RPGGameModeBaseクラスのReportCharacterHPisDamaged() 関数を実行します。
RPGGameModeBaseクラスのReportCharacterHPisDamaged() 関数は、
で、BlueprintImplementableEventを使用しているので実装部はBP側です。
そのBPにおける実装を以下のように変更しました。
これならDamageHPがマイナスの場合は「ほどHPが回復しました。もしくはHPがMaxまで上がりました。」と表示されるはずです。
最後にTestCombatActionItemクラスのBeginExecuteAction()関数内の事を以下に示したように改良しました。
これで、アイテムを使用してHPが回復した場合も正しく表示されるはずです。
試してみます。
KUMOに回復薬を使用しました。
出来ています。今度はゴブリンに回復薬を使用しました。
きちんとコメントされていますね。
成功しているみたいですね。
ただし、アイテムを使用して変化するのはHPだけではありません。MPも変化します。それに対するコメントも追加しましょう。
1.4 戦闘時のMP変化に対するコメントの追加
基本的にはHPが変化した時と同じで良いと思います。ので同じように作成していきます。
まず以下の関数と同じ働きをMPに対してする関数を作成します。
GameCharacterクラスの関数なので同じクラスに作成します。
クラスからRPGGameModeBaseクラスの関数、ReportCharacterMPisDamaged() をReportCharacterHPisDamaged()関数の代わりに呼びます。
RPGGameModeBaseクラスからReportCharacterMPisDamaged()関数を以下に示したように宣言します。
Buildします。
成功したのでReportCharacterMPisDamaged()関数の実装をBPで行います。
実装の内容は、ReportCharacterHPisDamaged()関数とほぼ同じです。
MPの回復も表示されるようになりました。
今週はここまでにしておきます。セリフはどこかで一括で管理しないと訳わからなくなりそうです。
2. Design Parts
先週、Medieval_Kingdomの付属の村を開いたらあまりにも重すぎてPCが唸り声をあげたので村は自作する事にしました。
教科書のやり方を勉強してそれ通りに作成する方法もあるかもしれませんが、取りあえず作成してから勉強した方が学びが大きい気がします。ので適当に作成してみます。
2.1 村の作成
適当に作成しました。
中から見るとこんな感じです。
3. まとめと感想
今週はこれで終わりです。