UE4の勉強記録

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

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 新しい機能を追加する4

f:id:kazuhironagai77:20200913205138p:plain

<前文>

Fall Guysを見て思った事

正直、私でも作れそうと思いました。しかし同時に私にはこのゲームを発想する事は出来ないとも思いました。このゲームの肝はゲーム内で障害物競争を多人数でしたら面白いはずと言うアイデアと、水平に進む事で正解に近づき、垂直に落ちる事で失敗した事に気付くという人間の本能に直結したゲーム内容です。これは思いつかないです。

しかし世の中にはFall Guysのような面白いゲームを発想出来る人もきっといるはずです。これからはそういうアイデアを持った個人が開発したゲームがAAAの何百億とかけたゲームより売れる時代が来るんでしょうね。そして先週も書きましたが日本文化は世界の中で非常に独特で、そういうアイデアが生まれやすい土壌があると思っています。この日本からゲーム一本で何百億も稼ぐ人が出てくると思います。

そう考えるとこれからの時代はゲームを作って一発当てる人生もアリかも知れません。

ゲーム好きな人は潜在的な頭の良さはピカイチだったのに、学校の勉強を全くしないで人生のレールから外れてしまった人が多いと聞きます。そういう人たちは敢えてゲームを作って一発狙った方が色んな意味で豊かな人生が歩めるじゃないでしょうか。確かにゲームエンジンを使用してゲームの制作が出来る様になるのは決して簡単ではないです。Computer Scienceの分野ではトップレベルのアメリカの大学を卒業した(卒業論文は査読付きの雑誌に掲載された)私でも正直難しいと思います。

しかし元々頭が良い人が正しい方法で勉強すれば理解出来ないレベルの難しさではないと思います。ここで大切なのは正しい方法で教える教材です。UE4に限りませんが、ゲームエンジンの使用方法やゲーム制作を教える教材は、日本語英語に限らず、それで勉強してもゲームを作れるまでには理解が深まる事はないものが多いです。

英語の勉強に例えると分かり易いですが、単語ばっかし覚えてる人がいたとします。そういう人が生の英語を聞くと一字も聞き取れなくて、英語難しい、俺には一生英語を話せるのは無理。と勘違いしてしまいます。しかし本当は、生の英語を聞き取る為には別な勉強が必要なだけです。英語をしゃべったり書いたり出来る様になるためにも別な勉強が必要です。これらの事を総合的に学べば3カ月もすればそれなりに英語で考えれるようになって、聞いたり、書いたり、しゃべったりがそれなりですが出来る様になります。

そういう人達向けにUE4の使い方を教える講座とか作ったら売れるかもしれませんね。

それでは今週の勉強を始めます。

<本文>

今週も、programming partとdesign partに分けてやって行きます。

Programming part

先週、途中で終わった戦闘中のアイテムの使用の機能を完成させます。

Design part

村の作成を続けます。

1. Programming Parts

1.1 AttackTarget()関数の見直し

f:id:kazuhironagai77:20200913205250p:plain

先週、アイテムを使用した際にこの関数を呼ばなかったから戦闘の途中で動作が止まってしまいました。

今回はこの関数の機能から調べていきます。

f:id:kazuhironagai77:20200913205323p:plain

まず、TestCombatAction()を作成しています。

f:id:kazuhironagai77:20200913205342p:plain

あれ、この作成されたTestCombatActionのBeginExecuteAction()関数を見てみると、敵に(自分の攻撃力‐敵の防御力)のダメージを与えているだけですね。

普通に攻撃した場合はこれでいいですが、魔法やItemを使用した場合は困りますね。

確か教科書に特殊攻撃をした場合の例が載っていたはずです。それを見てみましょう。

教科書の10章の6節Abilities logicを読み直すと、

f:id:kazuhironagai77:20200913205359p:plain

単に攻撃力を2倍に設定して攻撃が終わったら元に戻しているだけのようです。

しかし本来ならばこれはItem専用のTestCombatActionクラスを作成して、それを使用すべきなはずです。

のでそうしましょう。

1.2 Item専用のTestCombatActionクラスの作成

1.2.1 Item専用のTestCombatActionクラスを呼び出す関数をCombatUIWidgetクラスに作成する。

f:id:kazuhironagai77:20200913205429p:plain

f:id:kazuhironagai77:20200913205437p:plain

まず、CombatUIWidgetクラスにUseItemInCombat()関数を追加しました。この関数がItemのためのTestCombatActionを呼び出します。

このCombatUIWidgetクラスからBPクラス

f:id:kazuhironagai77:20200913205459p:plain

が作成されています。UE4C++のコードを変えるとその派生のBPに問題が起きる時があったので、今回はしっかり確認します。

まずbuildします。

f:id:kazuhironagai77:20200913205521p:plain

これは問題ありませんでした。

しかしCombatUIからこの新しく作成した関数、UseItemInCombat()を呼び出そうとしたら出来ません。

f:id:kazuhironagai77:20200913205543p:plain

うーん。何で?

念のためUE4 editor側からCompileしたら

f:id:kazuhironagai77:20200913205607p:plain

今度は出て来ました。

うーん。良く分からないですが、これ以外は特に問題なかったです。

1.2.2 UseItemInCombat()をBPから使用する。

以下に示したのが、AttackTarget()関数を呼び出しているBPで攻撃の対象を選択した時に実行されます。

f:id:kazuhironagai77:20200913205639p:plain

これ見るとAttackTargetを選択してActionPanelを隠してコメントを表示する事しかしていません。

今度は私が先週作成したItemを選択し、対象となるキャラを選択した時のコードです。

f:id:kazuhironagai77:20200913205720p:plain

ここで全部実行していました。これは間違っていましたね。ここですべき事は、

  • AttackTargetを選択して
  • ActionPanelを隠して
  • コメントを表示する

の3つだけです。これも直す必要がありますね。

取りあえず、以下のように変更しました。

f:id:kazuhironagai77:20200913205808p:plain

AttackTargetはそのまま使用していますが、対象となるキャラが自分の場合もあるのでこの辺からテストしてみます。

f:id:kazuhironagai77:20200913205831p:plain

あれ。これでも戦闘の途中で終わってしまいます。

一時間以上かかりましたがとうとう原因らしきものを見つけました。以下の部分でItemやRunを選択した時に次のノードを実行する事なく終了しています。

f:id:kazuhironagai77:20200913205850p:plain

以下のように直しました。

f:id:kazuhironagai77:20200913205909p:plain

取りあえず次のノードの繋いで試してみます。

今度は最後までいきました。

f:id:kazuhironagai77:20200913205927p:plain

ああ。びっくりしました。ずっとCombat engineのコードを追っていました。こんな簡単な所を見落としていたとは。

それでは、本来の目的のUseItemInCombat()関数をAttackTarget()関数の代わりに使用します。

といっても中身の実装を全く作成していないので中身はAttackTarget()関数をそのままコピーしました。

f:id:kazuhironagai77:20200913205948p:plain

AttackTarget()関数の代わりにUseItemInCombat()関数を使用します。

f:id:kazuhironagai77:20200913210004p:plain

普通に動きました。

ついでに使用したアイテムを保持しているitemから消します。

f:id:kazuhironagai77:20200913210021p:plain

あれ、道具が全部消えています。

f:id:kazuhironagai77:20200913210039p:plain

これRemove()関数を使用したら一個だけ消えるから…と言う事で前に直したヤツをそのまま使用しているんですが、直した時に間違えたみたいですね。

ブログを見直したら、8月2日のブログで間違った方法で直していました。

f:id:kazuhironagai77:20200913210059p:plain

成程、ThirdPersonCharacterクラスのtext配列からGameInstanceクラスのFStringのTArrayに変更したからRemove()が所持しているitemから一つだけ消去すると勘違いしたみたいですね。Removeは一種類のアイテムを全て消去するので、テストした時にそれぞれの種類のアイテムを一つだけ所持していて気が付かなかったみたいですね。

f:id:kazuhironagai77:20200913210130p:plain

こっちに戻す必要がありますね。これをまず直してしまいましょう。

1.2.3 Itemの消費バグの直し

直しました。

f:id:kazuhironagai77:20200913210152p:plain

テストします。

ダークイーサーを3個購入して戦闘で一つ使用しました。

f:id:kazuhironagai77:20200913210237p:plain

出来ているみたいですね。

ついでに通常のItem使用の場合も直しておきます。

f:id:kazuhironagai77:20200913210311p:plain

テストします。

回復薬が3つあります。一個使用します。

f:id:kazuhironagai77:20200913210328p:plain

一回Pause画面を閉じて開き直しました。

f:id:kazuhironagai77:20200913210345p:plain

回復薬が一個減っています。出来ているようです。

1.2.4 Item専用のTestCombatActionクラスの作成

時間がかかってしまいましたが今度こそ、Item専用のTestCombatActionクラスを作成します。

f:id:kazuhironagai77:20200913210411p:plain

前どうやって作成したのか忘れてしまいました。のでこれで作成します。

まず、動くのかの確認が必要なので実装部はTestCombatActionクラスと全く同じにします。

f:id:kazuhironagai77:20200913210503p:plain

そしてCombatUIWidgetクラスからTestCombatActionItemを作成します。

f:id:kazuhironagai77:20200913210523p:plain

これでTestCombatActionクラスを使用した場合と全く同じに動くはずです。

試してみます。

f:id:kazuhironagai77:20200913210543p:plain

問題なく戦闘中にItemを使用できました。

f:id:kazuhironagai77:20200913210607p:plain

使用したitemは無くなっています。

1.2.5 TestCombatActionItemの改良

取りあえず以下のように改良しました。

f:id:kazuhironagai77:20200913210634p:plain

f:id:kazuhironagai77:20200913210643p:plain

f:id:kazuhironagai77:20200913210655p:plain

f:id:kazuhironagai77:20200913210708p:plain

これでBeginExecuteAction()関数を呼ぶ前にSetItemProperty()を呼べば、Itemが変化させるMP値とHP値をTestCombatActionItemクラスにパスする事が出来ます。

それを踏まえて、UCombatUIWidgetクラスの関数を以下のように改良しました。

f:id:kazuhironagai77:20200913210737p:plain

f:id:kazuhironagai77:20200913210746p:plain

これで使用したアイテム分のHPとMPがターゲットに追加されるはずです。

テストしてみます。

先ず戦闘開始前のそれぞれのHPとMPは以下の通りです。

f:id:kazuhironagai77:20200913210815p:plain

f:id:kazuhironagai77:20200913210823p:plain

KUMOにダークイーサーを使用します。

f:id:kazuhironagai77:20200913210846p:plain

KUMOはゴブリンに攻撃され、更に自分が使用したダークイーサーの作用でHPが10減り、MPが20減るはずです。

f:id:kazuhironagai77:20200913210913p:plain

その通りの結果になりました。

今度は、イーサーをKUMOに使用してみます。

f:id:kazuhironagai77:20200913210940p:plain

KUMOはゴブリンに攻撃され、更にHPが10減りますが、使用したイーサーの作用で、MPが20増えるはずです。

f:id:kazuhironagai77:20200913211004p:plain

その通りの結果です。

こんどはKUROに回復薬を使用します。

f:id:kazuhironagai77:20200913211024p:plain

回復薬を使用したのでHPが100まで回復したのですが、その後にゴブリンに攻撃されたので10下がって90になりました。

f:id:kazuhironagai77:20200913211049p:plain

この後、ゴブリンに回復薬が効くのか試したかったのですが、KUMOが攻撃したら一撃で死んでしまいました。

のでゴブリンの種族値をいじってHPを100にしました。いかに一回KUMOが攻撃した後の図を示します。

f:id:kazuhironagai77:20200913211115p:plain

ゴブリンに回復薬を使用します。

f:id:kazuhironagai77:20200913211138p:plain

ゴブリンのHPが20回復しました。

f:id:kazuhironagai77:20200913211203p:plain

一応出来ていますね。

1.3 戦闘時のitem使用におけるコメントの直し

アイテムを使用した時のコメントがおかしいのでそれを直します。

まず、最初の部分だけ直しました。

f:id:kazuhironagai77:20200913211240p:plain

道具を選択したら、道具、選択した道具の名前、そして使用する相手が表示されます。

以下に追加したコードを示します。

CombatUIで道具ボタンをクリックした時に実行されるコードです。

f:id:kazuhironagai77:20200913211316p:plain

CombatItemウィジェットの道具の一つ(例えば回復薬)を選択した時に実行されるコードを以下に示します。

f:id:kazuhironagai77:20200913211335p:plain

TargetCharacterウィジェット内でitemを使用する相手を選択した時に実行されるコードです。

f:id:kazuhironagai77:20200913211355p:plain

それと大変なバグを一個見つけました。

攻撃ボタンを押した後、更に道具ボタンを押せます。そうすると以下に示したようなコメントが表示されてしまいます。

f:id:kazuhironagai77:20200913211447p:plain

後で直します。

次のコメントは以下のように表示されています。

f:id:kazuhironagai77:20200913211507p:plain

これが攻撃を選択した場合は、

f:id:kazuhironagai77:20200913211530p:plain

となっています。

まず、“KUMO”がゴブリンを攻撃しました。に当たる文章が表示出来る様にします。

結果から示すと以下のような文章を表示するように出来ました。

f:id:kazuhironagai77:20200913211608p:plain

f:id:kazuhironagai77:20200913211616p:plain

以下にコードを示します。

CombatItemウィジェットに追加した部分です。

f:id:kazuhironagai77:20200913211636p:plain

TargetCharacterウィジェットに追加した部分です。

f:id:kazuhironagai77:20200913211656p:plain

最後に以下の部分を直します。

f:id:kazuhironagai77:20200913211724p:plain

先程作成したTestCombatActionItemクラスのBeginExecuteAction()関数内で実行される以下の関数がこの部分のコメントに関わっています。

f:id:kazuhironagai77:20200913211744p:plain

のでC++の挙動にも注意しながら直していきます。

まず、ReportDamageHPtoRPGGameModeBase()関数は以下に示したように、GameCharacterクラスの関数で、RPGGameModeBaseクラスのReportCharacterHPisDamaged() 関数を実行します。

f:id:kazuhironagai77:20200913211816p:plain

RPGGameModeBaseクラスのReportCharacterHPisDamaged() 関数は、

f:id:kazuhironagai77:20200913211841p:plain

で、BlueprintImplementableEventを使用しているので実装部はBP側です。

そのBPにおける実装を以下のように変更しました。

f:id:kazuhironagai77:20200913211908p:plain

これならDamageHPがマイナスの場合は「ほどHPが回復しました。もしくはHPがMaxまで上がりました。」と表示されるはずです。

最後にTestCombatActionItemクラスのBeginExecuteAction()関数内の事を以下に示したように改良しました。

f:id:kazuhironagai77:20200913211938p:plain

これで、アイテムを使用してHPが回復した場合も正しく表示されるはずです。

試してみます。

KUMOに回復薬を使用しました。

f:id:kazuhironagai77:20200913212005p:plain

出来ています。今度はゴブリンに回復薬を使用しました。

f:id:kazuhironagai77:20200913212023p:plain

きちんとコメントされていますね。

成功しているみたいですね。

ただし、アイテムを使用して変化するのはHPだけではありません。MPも変化します。それに対するコメントも追加しましょう。

1.4 戦闘時のMP変化に対するコメントの追加

基本的にはHPが変化した時と同じで良いと思います。ので同じように作成していきます。

まず以下の関数と同じ働きをMPに対してする関数を作成します。

f:id:kazuhironagai77:20200913212055p:plain

GameCharacterクラスの関数なので同じクラスに作成します。

f:id:kazuhironagai77:20200913212114p:plain

クラスからRPGGameModeBaseクラスの関数、ReportCharacterMPisDamaged() をReportCharacterHPisDamaged()関数の代わりに呼びます。

f:id:kazuhironagai77:20200913212143p:plain

RPGGameModeBaseクラスからReportCharacterMPisDamaged()関数を以下に示したように宣言します。

f:id:kazuhironagai77:20200913212221p:plain

Buildします。

f:id:kazuhironagai77:20200913212240p:plain

成功したのでReportCharacterMPisDamaged()関数の実装をBPで行います。

f:id:kazuhironagai77:20200913212307p:plain

実装の内容は、ReportCharacterHPisDamaged()関数とほぼ同じです。

f:id:kazuhironagai77:20200913212326p:plain

MPの回復も表示されるようになりました。

今週はここまでにしておきます。セリフはどこかで一括で管理しないと訳わからなくなりそうです。

2. Design Parts

先週、Medieval_Kingdomの付属の村を開いたらあまりにも重すぎてPCが唸り声をあげたので村は自作する事にしました。

教科書のやり方を勉強してそれ通りに作成する方法もあるかもしれませんが、取りあえず作成してから勉強した方が学びが大きい気がします。ので適当に作成してみます。

2.1 村の作成

適当に作成しました。

f:id:kazuhironagai77:20200913212412p:plain

f:id:kazuhironagai77:20200913212421p:plain

中から見るとこんな感じです。

f:id:kazuhironagai77:20200913212438p:plain

f:id:kazuhironagai77:20200913212446p:plain

f:id:kazuhironagai77:20200913212501p:plain

3. まとめと感想

今週はこれで終わりです。

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 新しい機能を追加する3

f:id:kazuhironagai77:20200906193020p:plain

<前文>

Vtuberについて2

しかしvtuberというのは凄い発明ですね。幾ら見ても飽きないです。びっくりしたのはボイスチェンジャーを使用すればおじさんですら美少女vtuberに成れる事です。個人的にはGoogle検索エンジンに匹敵する発明だと思いました。MMDを初めて見た時も思いましたが、日本文化は他に類を見ない発想とそれを実現する科学技術を持つ稀有なもののようです。

こういう事は誇っていいと思います。いつも日本凄いと言っているネトウヨと言われる人達は、こういう事は決して褒めないですね。何でしょう。日本文化が他に類を見ない発想とそれを実現する科学技術を持つ稀有な文化だと嫌なんでしょうか?

しかし問題もある事も分かりました。見終わっても何にも学んだ事がないです。しかも時間を大量にとる為、後で別の動画を見る事も出来ません。先々週、あんなに心配していたEpic games とアップル社の裁判も現在どうなっているのか全く分かりません。大学教授とかがvtuberになって講義をストリームしてくれると遊びながら学習出来て更に良いですね。

遊びながら学習と言えば、私が作成している英語の発音が学べるゲームですが、LとRの音を持つminimal pairな単語を大量に追加しました。その音でテストしたらLやRの音が一種類でない気がしてきました。Dark LとLight Lについては私も知っていますが、それ以上にLの音があるような気がしています。そこで思い出したのですが、アメリカ人がLの発音する時、実際はThみたく舌を噛んでいる人が一定数いた気がします。Rの発音でも下の先を丸めるRと舌の奥をスプーンみたく丸めて発音するRの音は違う気がします。日本人でLとRの発音が出来ている人でもLとRを聞いたときに区別が付かないのは、単純にLとRに沢山の音があってその全部の音を知らないからかもしれません。

私は音声学を勉強したわけではないので、そういう説があるのかは知りません。しかし例え無くても、日本人がLとRの区別が付かないのは単純にLとRに沢山の音があってその全部の音を知らないから説は仮説としてはあり得る気がしています。

それでは今週の勉強を始めます。

<本文>

先週からゲームのアート的な部分も制作し始めました。その結果プログラミングの勉強がおろそかになりがちなので、今週からプログラミングパートとデザインパートを分けて勉強する事にします。

Programming Part

今週はCh4_3 をGithubにでも上げようと思っていたのですが先週から考えた結果、あまりメリットがないと結論が出ました。今までも使用しなくても問題なくやってこれましたし、所詮一人で作成していますから。のでGithubにこのプロジェクトを上げるのは止めます。でなにをするかと言うと、

戦闘システムの「道具」と「逃げる」を選択した場合を作成していなかったのでそれを作成します。

f:id:kazuhironagai77:20200906193308p:plain

デザイン編

今週は先週作成したショップをマップ内に配置して道具屋と武器屋を作成します。

1. Programming Parts

1.1 逃げるボタンの実装

まず、逃げるボタンを選択したらCombatUIウィジェットの変数CombatSelectedのenumをRunにセットします。

f:id:kazuhironagai77:20200906193358p:plain

あれ、「逃げる」って選択をとる為には、BPの変更だけでなくUE4C++からの変更や戦闘エンジンそのものの変更も必要ですね。

f:id:kazuhironagai77:20200906193417p:plain

戦闘が終わった時は二つの状態しか設定していませんでした。負けた時と買った時です。これに逃げた時を追加する必要がありますね。

f:id:kazuhironagai77:20200906193435p:plain

CombatEngineのCombatEngine.hに設定されているenumの CombatPhaseにCPHASE_MakeOffを追加しました。

これで逃げるボタンを選択したら、RPGGameModeBaseクラスにあるCombatEngineの変数内の変数PhaseがCPHASE_MakeOffに変更されるようにすればいいはずです。

そのためには、まずCombatEngineクラスのTick()関数にCase CombatPhase::CPHASE_MakeOffを追加します。

f:id:kazuhironagai77:20200906193452p:plain

因みに、CPHASE_VictoryとCPHASE_GameOverは

f:id:kazuhironagai77:20200906193507p:plain

こんな感じでPhaseを変更しています。

あれ?

f:id:kazuhironagai77:20200906193522p:plain

Phase変数はPublicに指定されているのに、

f:id:kazuhironagai77:20200906193536p:plain

SetPhase() 関数がprotectedに指定されている。

支離滅裂過ぎる。

いくらなんでも私はこんなコードは書きません。教科書を見たらやっぱり

f:id:kazuhironagai77:20200906193553p:plain

教科書にそう書かれていました。

うん。あんまり教科書を信用するのも善し悪しですね。

今回はこのままにして置きますが、CombatEngine3を自作する時は全部書き直します。

変数、PhaseをCPHASE_MakeOffに変更する方法ですが、

  1. CombatEngineクラス内に、Phase変数の値をCPHASE_MakeOff に変更するPublicな関数を作成。
  2. RPGGameModeBaseクラスにその関数を呼ぶBPから実行可能な関数を作成。
  3. CombatUIウィジェットで逃げるボタンを選択した時にその関数を呼び出せるように実装。

でやってみます。

CombatEngine.hにRPGGameModeクラスから呼び出せる関数、SetPhaseToMakeOff()関数を宣言しました。

f:id:kazuhironagai77:20200906193647p:plain

更にCombatEngine.cppにSetPhaseToMakeOff()関数を実装します。

f:id:kazuhironagai77:20200906193723p:plain

今度は、RPGGameModeBaseクラスからこの関数を呼ぶ関数、SetCombatEnginePhaseMakeOff()を作成します。

f:id:kazuhironagai77:20200906193753p:plain

f:id:kazuhironagai77:20200906193801p:plain

まず、UFUNCTIONがBlueprintCallableなのでBPからこの関数は呼べるはずです。

BPとUE4C++そして生のC++の関係は民間、政府、外国の関係と思うと分かり易いと前に書きましたが、民間企業が自国の政府に要請してその政府から更に外国の政府に要請の手順を踏む事で外国政府に要件を聞いてもらうように、BP→UE4C++(RPGGameModeBaseクラス)→生のC++(CombatEngine)となっています。

ビルドも成功しました。

f:id:kazuhironagai77:20200906193841p:plain

本当にBPからPhase変数の値をCPHASE_MakeOffに変更出来ているのか確認するために以下のコードをRPGGameModeBaseクラスのTick()関数に追加します。

f:id:kazuhironagai77:20200906193859p:plain

テストします。

逃げるボタンを選択したらRPGGameModeBaseクラスのSetCombatEnginePhaseMakeOff()関数を呼び出すように実装しました。

f:id:kazuhironagai77:20200906193926p:plain

Phase変数の値はCPHASE_MakeOffに変更されているみたいですね。

f:id:kazuhironagai77:20200906193946p:plain

今度はこの中を正しく実装していきます。

f:id:kazuhironagai77:20200906194024p:plain

まずisNotPrintyet変数ですがこの中のコードを一回だけ実行するための変数です。一回実行したらFalseにセットします。それだけです。

この関数内で実行されるReportFightIsOver()関数が全てを管理しています。

f:id:kazuhironagai77:20200906194042p:plain

ReportFightIsOver()関数はBlueprintImplementableEventなので実装はBPで行います。

まず最初の部分ですが

f:id:kazuhironagai77:20200906194058p:plain

戦闘に勝った場合と負けた場合の2つに分かれています。ここにescapeを追加する必要があります。

以下に勝った場合を示します。

f:id:kazuhironagai77:20200906194114p:plain

表示するセリフが示されています。

逃げた場合のセリフをここに作成する必要があります。

以下の部分は読みましたボタンを表示しているのとそのボタンがクリックされたのを確認しているだけなので変更は必要ないです。

f:id:kazuhironagai77:20200906194131p:plain

これが読みましたボタンです。

f:id:kazuhironagai77:20200906194145p:plain

その後の部分ですが、アニメーションを流しています。戦闘に勝った時は勝利のポーズ、負けた時は敗北のアニメーションを流しています。

f:id:kazuhironagai77:20200906194211p:plain

その後で、HadReadFightIsOver()関数を呼び出しています。

f:id:kazuhironagai77:20200906194230p:plain

以下にRPGGameModeBase.hで宣言されているHadReadFightIsOver()関数を示します。

f:id:kazuhironagai77:20200906194251p:plain

実装部はこんだけです。

f:id:kazuhironagai77:20200906194307p:plain

FightIsOverIsRead変数がtrueになるとTick()関数内の以下のコードが実行されます。

f:id:kazuhironagai77:20200906194324p:plain

成程、大体分かりました。

こんな感じに直しました。

まず新たなEnum, CombatOverStateを作成しました。以下に示した通り、VictoryとGameOverだけでなくEscapeがあります。

f:id:kazuhironagai77:20200906194344p:plain

このEnumを使用してReportFightIsOver()関数を以下のように変更しました。

f:id:kazuhironagai77:20200906194403p:plain

BPに移ってReportFightIsOver()関数の実装になります。Victory変数をBooleanタイプからCombatOverStateタイプに変更しました。

f:id:kazuhironagai77:20200906194418p:plain

当然、分岐もbranchからSwitchに変更しています。

f:id:kazuhironagai77:20200906194438p:plain

逃げた時のコメントを追加しました。

f:id:kazuhironagai77:20200906194455p:plain

逃走した時のアニメーションは要らないのでアニメーションパートはスキップします。

f:id:kazuhironagai77:20200906194512p:plain

これで出来たはずです。

テストします。

f:id:kazuhironagai77:20200906194528p:plain

逃げるを選択するとコメント欄に“KUMO”は逃走しました。と表示されました。

f:id:kazuhironagai77:20200906194544p:plain

そして元の場所に戻りました。出来ていますね。

1.2 道具ボタンの実装

今度は道具ボタンの実装をしていきます。最初はこっちの方が難しいと思ったのですがどうでしょうか?BPだけで実装出来そうな気もしています。

取りあえず道具ボタンを押したら、持っている道具が表示されるように実装してみました。

f:id:kazuhironagai77:20200906194602p:plain

こんな感じで表示されています。

f:id:kazuhironagai77:20200906194620p:plain

Itemウィジェットをそのまま使用したのですが字が切れてしまってますね。

カーソルを道具ボタンの上に置くと、

f:id:kazuhironagai77:20200906194644p:plain

その道具の詳細が表示されます。これはカッコイイです。

よし決めました。ここでItemウィジェットを使用するのは止めます。新しくCombat_Itemウィジェットを作ってそれを使用します。

f:id:kazuhironagai77:20200906194702p:plain

作りました。ItemウィジェットをDuplicateした物に文字の大きさを変えただけです。

f:id:kazuhironagai77:20200906194718p:plain

道具の詳細を表示するウィジェットも新しく作りました。

f:id:kazuhironagai77:20200906194735p:plain

良い感じです。

今度はアイテムボタンがクリックされた場合の実装をします。

まずクリックされたアイテムが何なのかを保持するためにCombatUIウィジェット内に変数を一個作成します。

f:id:kazuhironagai77:20200906194750p:plain

ボタンをクリックした時にこの変数にクリックされたボタンのアイテム名を保持出来るように

f:id:kazuhironagai77:20200906194807p:plain

CombatItemにCombatUIをパスしておきます。

更にcustom event, ItemButtonClickedを作成して

f:id:kazuhironagai77:20200906194822p:plain

それをCombatItemボタンが押された時に呼び出します。

f:id:kazuhironagai77:20200906194836p:plain

取りあえずここでテストします。

f:id:kazuhironagai77:20200906194851p:plain

回復薬をクリックすると左上に回復薬と表示されます。ここまでは正常に動いてるようです。

今度は、アイテムをクリックしたら対象の人が表示されるようにします。といっても対象はユーザーが操作するキャラかモンスターの2種類しかいませんが。

そう言えば、魔法を選択した場合、どうやって実装しているのかチェックし忘れていました。そっちを先に見ます。

f:id:kazuhironagai77:20200906194909p:plain

魔法を選択すると使用出来る魔法がScroll boxであるChoose内に表示されます。そしてその中から魔法を選択すると

f:id:kazuhironagai77:20200906194932p:plain

魔法の対象となるモンスター名が表示されます。

魔法を表示するウィジェットは、

f:id:kazuhironagai77:20200906194947p:plain

f:id:kazuhironagai77:20200906194955p:plain

f:id:kazuhironagai77:20200906195002p:plain

で結構しっかり作り込まれていました。

これは、Combat_Itemを作成する前に見るべきでしたね。ちょっと遅きに失してしまいましたが、今から見ていきます。

f:id:kazuhironagai77:20200906195029p:plain

まず、TargetとTargetUIがあります。TargetはGameCharacterタイプの変数で攻撃対象のモンスターを保持しています。TargetUIはCombatUIタイプの変数でこのMagicUIを保持しているCombatUIのインスタンスを保持しています。

f:id:kazuhironagai77:20200906195048p:plain

TargetとTargetUIの値はMagicウィジェット作成時にparameterとしてパスされています。TargteUIはselfをパスすればいいだけですが、Targetはどうやって収得しているか分かりません。

f:id:kazuhironagai77:20200906195113p:plain

分かりました。この関数が取ってきていました。

この関数、UE4C++のCombatUIWidgetクラスで作成していました。

f:id:kazuhironagai77:20200906195127p:plain

f:id:kazuhironagai77:20200906195134p:plain

うーん。成程、最適化からは程遠いですが、一応敵のGamecharacterクラスを返していますね。

更にMagicボタンがクリックされた場合を見て行きます。

f:id:kazuhironagai77:20200906195151p:plain

CombatUIウィジェットのTarget内のChildrenを全部消しています。魔法ボタンをクリックした時に同じ事を既にやってなかったかなと思って見直して見ると

f:id:kazuhironagai77:20200906195209p:plain

やってなかったです。

ただし、さっき作成したItemボタンをクリックした時は、

f:id:kazuhironagai77:20200906195226p:plain

思いっきりやってます。どっちがベターな方法なんでしょうか?後で考えます。

Magicボタンに戻りますが、

f:id:kazuhironagai77:20200906195255p:plain

その対象のモンスターが生きているのか確認していますね。これは1対1のバトルに変更した今では要らないはずですが、あっても問題がある訳でもないので残しているのでしょうね。

f:id:kazuhironagai77:20200906195313p:plain

その後で、今度はTargetに入るボタン、つまり対象となるモンスターを表示するウィジェットを作成しています。AttackTargetOptionウィジェットは後でみます。

f:id:kazuhironagai77:20200906195331p:plain

最後にコメントを表示していますね。これは大切でした。

AttackTargetOptionウィジェットも次いでに見てみましょう。

f:id:kazuhironagai77:20200906195346p:plain

f:id:kazuhironagai77:20200906195352p:plain

f:id:kazuhironagai77:20200906195406p:plain

ボタンを表示するためのウィジェットなのですが、CanvasPanelを使用していますね。

f:id:kazuhironagai77:20200906195424p:plain

コメントを最後に表示する処以外は普通ですね。

大体分かりました。魔法の時のやり方が楽な気がしてきました。

ただ、Targetは結局、RPGGameModeBaseクラスにある変数、EnemyMonsterとRPGGameInstanceクラスにあるMyYourHero変数なので、parameterとしてパスしなくてWidget内でアクセス出来るのでどうしようかなと思っています。

よし決めました。基本は、魔法を選択した時のやり方で多少マイナーチェンジをします。

こんな感じに作成しました。

まずCombatUIウィジェットで道具が選択された時です。

f:id:kazuhironagai77:20200906195443p:plain

そして、表示されたアイテムの一つがクリックされた時です。

f:id:kazuhironagai77:20200906195501p:plain

ここで開かれるTargetCharacterウィジェットは、AttackTargetOptionウィジェットを参考にして作成しました。

TargetCharacterウィジェットから作成された対象となるキャラを選択した時は、

f:id:kazuhironagai77:20200906195515p:plain

こうなります。

まだセリフなどは追加していませんが、これで一応動くはずです。

テストします。

f:id:kazuhironagai77:20200906195532p:plain

回復薬を選択します。

f:id:kazuhironagai77:20200906195547p:plain

使用する対象が表示されました。KUMOを選択します。

f:id:kazuhironagai77:20200906195603p:plain

あれ、動かなくなってしまいました。

調べたらこの関数を呼ぶ必要があるみたいです。

f:id:kazuhironagai77:20200906195619p:plain

f:id:kazuhironagai77:20200906195631p:plain

これは、CombatEngineを見直す必要がありますね。

今週はここまでにして残りは来週作成します。

2. Design Parts

2.1 道具屋の配置と作成

先週作成した店を配置してみます。

f:id:kazuhironagai77:20200906195704p:plain

外から見た感じです。結構いい雰囲気が出ていますね。

f:id:kazuhironagai77:20200906195719p:plain

店の後ろに回って見ました。雰囲気は良いですが、何か全体的に暗いですね。

f:id:kazuhironagai77:20200906195736p:plain

店の中に入って見ます。やはりちょっと暗すぎますね。

f:id:kazuhironagai77:20200906195751p:plain

横から見た風景です。これは暗すぎませんね。

f:id:kazuhironagai77:20200906195806p:plain

Eを押せば道具屋のUIが始まります。

まあ、最初の段階としては良い感じです。これで道具屋と武器屋の区別が付くようにします。

f:id:kazuhironagai77:20200906195823p:plain

色々考えたんですがこれが一番分かり易いです。

これでいきます。

f:id:kazuhironagai77:20200906195839p:plain

武器屋も作成しました。

f:id:kazuhironagai77:20200906195855p:plain

中身です。

2.2 これからの課題

一応、これで道具屋と武器屋が出来ました。この後、村や町そして城を作成しようと思います。それぞれ別なlevelに作成する予定です。以下の事を考える必要があると思っています。

  • 街全体のサイズ。ランドスケープで制作する場合の設定はどうすればいいのか。ランドスケープを使用しない場合は、町は平らになる。無料で配布されているマップを使用した場合はどうなのか?
  • 別なlevelに移行して戻った場合、前のlevelで採取したアイテムやモンスターが再生されて配置される。一度取ったら再生されないようにするにはどうしたら良いか?
  • Weapon ShopやItem Shopを日本語表示したい。

2.3 無料のマップの確認

Medieval Kingdomの付属のマップを開いて見ていたらPCが凄い音を立てました。正直こんなvideo cardに負担をかけるマップは使用したくないです。自分で作成する事にします。

ただもう時間が無くなってしまったので残りは来週します。

3. 感想とまとめ

今週はここまです。

 

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 新しい機能を追加する2

f:id:kazuhironagai77:20200830201127p:plain

<前文>

Vtuberは新たな日本の輸出品になれるのか?

先週初めてvtuberを見ましたがこんなに面白い物とは思いませんでした。「絵が動いて声優がしゃべっているだけでしょう。」と思っていましたし実際そうなんですが、受ける印象が全く違います。何が違うのかと言うとアイドルと一緒に遊んでいる錯覚に捕らわれるんです。しかもVRと比較にならない位の没入感があります。

こんなの日本だけじゃなくてアメリカでも大受けだろうと思ったら実際に英語をしゃべるvtuberも結構いるみたいです。ただ私が調べた限りではアメリカのマッチョ信仰のせいなのか、英語圏vtuberは総じてアイドル感が足りない感じでした。何か女戦士と冒険してる感じでした。これならアメリカ人も日本のvtuberを見ると思います。

そしたら既にバイリンガルvtuberなる存在がある事を知りました。日本語と英語をチャンポンで話し英語しか分からなくてもアイドル(vtuber)と一緒に遊んでいる錯覚が失われない様にしています。更に英語圏の視聴者からは本物の日本語の勉強にもなる。との評価まで出ています。もうこれは自動車に代わる新たなmade in Japanの主力輸出品になるんじゃないのかと期待すらしています。

ただ一気に現実に引き戻される場面もありました。それはあるvtuber英語圏ではかなりsensitiveな内容をペロッと言った時に、共演していたバイリンガルvtuberが滅茶苦茶焦って、結局そのセリフだけ英語に訳さないでやり過ごしたのを見た時でした。勿論vtuberは可愛いのでそういう内容をしゃべっても全然許さる場合が多いかもしれませんし、本人が信念を持って発言している場合は、無理に意見を変える必要もないです。しかし英語圏におけるsensitiveな内容は知っておいた方が無駄な争いは避けれますし、場合によっては触れない方が賢明だとの判断もつけられます。

私は機械学習や深層学習をバカにしていましたが、実際はそれらの技術のおかげで自動翻訳技術、並びに自動朗読技術が格段に向上しています。英語の全くしゃべれない日本人vtuberでもこれらの翻訳機を使用して英語でアメリカ人と会話出来る日は直ぐそこまで来ています。その時に問題にならないように10年アメリカに住んでいた私が知る限りでアメリカ文化におけるsensitiveな話題を集めてみました。

人間として扱ってもらえないLevel

  • 犬を虐める。(猫は問題ない)
  • 馬を食べる。クジラを食べる。(牛、豚は問題ない。馬刺しを食べたよ。は言ってはいけない。)
  • ロリコン(アニメを見る人もここに分類される場合があるので注意!最悪警察に捕まる可能性も)
  • 人種差別的な発言、行動を取る。

二度と口を聞いてもらえないLevel

  • 軽はずみに人種差別されたと断言する。
  • 羨ましい時にenvyを使用する。憎らしい相手にGod damn youと言うなど。(十戒に相手を妬んではいけない。憎んでもいけない。と書かれているせいか、アメリカ人は妬まれたり、憎まれたりする事に慣れていない。非常に嫌がる。)
  • 性的なジョークを言う。
  • 奴隷制などの触れてほしくない話題を振る。(政治、宗教、人種も含む。)
  • 英語を間違える。
  • 怒る、怒鳴る。(最悪警察に逮捕される。上司が部下に怒鳴るのも×。)

顔には出さないが内心凄い嫌がっているLevel

  • 聞いているだけで返事をしない。
  • 親しさを表すために差別的な表現を敢えて使う。
  • 挨拶、握手をしない。
  • 込み入っている状況の時に、話しかけられると困るので他人のふりをする。もしくは見てないふりをする。
  • 誰かが話している時に割り込む。(日本人特に多い。滅茶苦茶礼儀知らずに思われる。反対意見があっても相手が話し終わるまで待つ。それから発言する。)
  • 納豆食べた後会話(めっちゃ匂っています。西洋人には納豆はゴミ箱の匂いなんです。)

実際にやってしまった場合は、その人との好意的な関係を修復するのは無理なのでズバッと諦めましょう。そして次に同じ間違いを繰り返さないようにしましょう。

それでは今週の勉強を始めます。

<本文>

先週から色々考えたんですが、兎に角、RPGを一本完成させようと思います。

そのためには

  • 3Dモデルはかなりおかしくても市販の物で代用する。Blenderから作成していたら時間がかかってゲームも3Dモデルも完成しない内に飽きてしまう可能性があるので。
  • ストーリーは適当でいい。
  • 音楽は後付け

で取りあえずゲームを完成させます。

1.アセットの確認

今持っているアセットで使えそうなのを確認します。

f:id:kazuhironagai77:20200830201348p:plain

これは魔法のエフェクトに使用出来ますね。

f:id:kazuhironagai77:20200830201404p:plain

これらはマップとして追加出来るみたいですね。ちょっとリアル過ぎるかもしれませんが候補としておきます。

良く考えたらCategoryでEnvironmentにセットすればマップに使用出来るアセットだけ表示されるでした。

f:id:kazuhironagai77:20200830201420p:plain

現時点で以下に示した分だけ所有していました。

f:id:kazuhironagai77:20200830201441p:plain

何点か非常に使えそうなのがあります。

f:id:kazuhironagai77:20200830201455p:plain

f:id:kazuhironagai77:20200830201501p:plain

f:id:kazuhironagai77:20200830201509p:plain

f:id:kazuhironagai77:20200830201516p:plain

f:id:kazuhironagai77:20200830201524p:plain

この辺から見てみます。

f:id:kazuhironagai77:20200830201544p:plain

これだけ使用すれば何とかなりそうな感じですね。

f:id:kazuhironagai77:20200830201600p:plain

こっちは凄いですがリアル過ぎますかね。

f:id:kazuhironagai77:20200830201616p:plain

これは完璧でしょう。

f:id:kazuhironagai77:20200830201910p:plain

これもかなり凄いですね。

f:id:kazuhironagai77:20200830201924p:plain

これも凄そうです。

決めました。

新しいプロジェクトを作成してそれにこれらのアセットを追加して観察してみます。

名前はTestEnvironmentsにしました。

追加します。

そう言えばそれぞれのアセットのサイズとか考えていませんでした。PCなら関係ないかもしれませんが、携帯電話ならサイズも考えないといけませんね。

Medieval Kingdomだけ容量が7.83GBもありました。これはそのままでは使用出来ないですね。

それではそれぞれのアセットを見てみます。

まず、Platformer Starter Packからです。

f:id:kazuhironagai77:20200830201944p:plain

滅茶苦茶凄いじゃないですか?

f:id:kazuhironagai77:20200830202001p:plain

f:id:kazuhironagai77:20200830202011p:plain

もうこれだけでいいやって感じです。

f:id:kazuhironagai77:20200830202035p:plain

Overviewです。Level designerならこれでマップを作成するんでしょうがそこまでは自分ではやりたくないですね。

念のために他のも見てみます。

Stylized desert environmentです。

f:id:kazuhironagai77:20200830202103p:plain

これはサンプルマップ内で動けるようには作成されていないみたいです。カメラが7か所に設置されているのでそれぞれからの風景が見れるはずですが操作の仕方が分かりません。

f:id:kazuhironagai77:20200830202303p:plain

こんなアクターが使用出来るみたいです。

まあいいです。次を見ましょう。

次はWatermill Environmentです。

f:id:kazuhironagai77:20200830202323p:plain

あれ。Overviewを開いていました。

Medieval Kingdomを見てみます。

f:id:kazuhironagai77:20200830202342p:plain

多すぎてどれ見ればいいのか分かりません。取り敢えずmap1を見てみます。

f:id:kazuhironagai77:20200830202412p:plain

凄いですが、PCのうねり声も凄くなりました。他のマップも大体同じみたいです。

確かにそれぞれ凄いですが、私はlevel designerになる気はないんで、なるべくなら一括で全部そろっている方が良かったです。

うーん。しょうがないLevel designも自分で作成しますか。

作成に必要な要素を絞ります。

街、村、城です。その中には、道具屋、武器屋、宿屋、教会、一般人の家が必要です。

その外には、草原、森、山、砂漠、雪原が欲しいです。

3Dモデルはここにある奴を使用する事にします。

f:id:kazuhironagai77:20200830202442p:plain

全部のアセット内のStatic meshはそれぞれ単体で使用出来る事は確認出来ました。

2.建物の作成

もう武器屋、道具屋、宿屋、教会、一般人の家はこれで良いです。

f:id:kazuhironagai77:20200830202522p:plain

https://docs.unrealengine.com/en-US/Engine/QuickStart/index.html

それよりデザインばっかりやっているとプログラム本当に忘れてしまう事を思い出しました。これからはデザインが主になる時が多いと考えられますが、必ずプログラムも書く事にします。

まず、壁用のmeshですが、Medieval Kingdomに良さそうなのがありました。

f:id:kazuhironagai77:20200830203308p:plain

そしたら裏が透けています。

f:id:kazuhironagai77:20200830203326p:plain

直します。

使用しているマテリアルのTwo Slidedに

f:id:kazuhironagai77:20200830203347p:plain

Checkを入れます。

このチュートリアルによるとMeshのDouble Sided Geometryにチェックを入れろとありますが、

f:id:kazuhironagai77:20200830203630p:plain

Collisionにしかその項目がありません。一応入れておきます。

f:id:kazuhironagai77:20200830203649p:plain

後ろからも透明でなくなりました。

出来ました。

f:id:kazuhironagai77:20200830203705p:plain

f:id:kazuhironagai77:20200830203713p:plain

中はこんな感じです。

f:id:kazuhironagai77:20200830203753p:plain

f:id:kazuhironagai77:20200830203801p:plain

f:id:kazuhironagai77:20200830203809p:plain

ちょっとリアル過ぎますが、上出来でしょう。

同じ物をアクター内に作成して移動しやすくします。

f:id:kazuhironagai77:20200830203829p:plain

f:id:kazuhironagai77:20200830203836p:plain

何故か中がひどく明るいです。

f:id:kazuhironagai77:20200830203901p:plain

アクター内のStaticMeshのMobilityをStaticに変更したら直りました。

f:id:kazuhironagai77:20200830203919p:plain

f:id:kazuhironagai77:20200830203930p:plain

作って行くうちにZ-fightingが大量に発生しました。

Z-fightingを避ける為にmesh同士が重ならない様にしたら今度は隙間が気になります。

f:id:kazuhironagai77:20200830203947p:plain

Actor内で使用しているstatic meshらが重なった時z-fightingを起こさないようにする方法が分かりません。

というか普通の3D-Graphics programming (OpenGL)で2つ以上のメッシュが完全に同じ位置に存在した時に起きるz-fightingの防ぎ方も知らないです。Rasterizationかfragment programmingの段階でz-fightingが起きないように事前に防げそうですがね。

この問題は後で考えます。

3.ちょっとだけプログラミングもやります

思い出したんですが、UE4のデザインばかりやっているとプログラミングの方を直ぐ忘れるんです。流石に1,2週間なら大丈夫でしょうが、1カ月経つと完全に忘れます。自分が書いたコードも他人が書いたコードと同じです。更に問題なのが何でそんな書き方をしたのかが分からなくなる事です。

これからはデザインを大量にやる必要が出て来ますが、毎週必ずプログラミングもやる事にします。

f:id:kazuhironagai77:20200830204013p:plain

今週はこの部分を直す事にします。これはLevel BPに書かれたコードで、ある特定の場所でキーボードのEを押した場合に実行されるコードが書かれた部分です。直したい事は幾つかあります。

一つ目はユーザーのinputとキャラの行動を管理するクラスは、ThirdPersonCharacterなのでこのコードをLevel BPからThirdPersonCharacterに移します。

2つ目はifの連続になっているのでSwitchを使用して見易くします。更に条件にEnumを使用する事でこれから増える条件にも対応出来るようにします。

3.1 コードの直し

まず、RPGGameInstance内で作成したBoolean変数を一括して管理出来るようにします。

f:id:kazuhironagai77:20200830204035p:plain

現時点では以下に示したようにバラバラで管理しています。

f:id:kazuhironagai77:20200830204053p:plain

f:id:kazuhironagai77:20200830204100p:plain

まずGameInstanceクラスで管理する必要があるか何ですが、お店の中で別なレベル(マップ)に移動する事は絶対ないので、GameInstanceクラスで管理する必要はないです。

GameModeクラスで管理します。

次にUE4C++で管理するかBPで管理するかですが、UE4C++で管理します。理由はUE4C++で管理する方が難しいからです。難しい事に慣れておけば簡単な事に対応する事はすぐ出来るからです。

まず、Enumを作成します。

UE4C++でのEnumの作成方法を忘れてしまいました。調べます。

Googleでは、お馴染みの教科書であるUnreal Engine 4 Scripting with C++ CookbookのEnumのページが一番最初に出て来ました。

f:id:kazuhironagai77:20200830204132p:plain

Sherif, William. Unreal Engine 4 Scripting with C++ Cookbook (Kindle Location 4135). Packt Publishing. Kindle Edition.

何か変ですね。普通は公式のページが最初に出てくるんですが。

次に見つかったのがこのサイトです。

f:id:kazuhironagai77:20200830204230p:plain

こんな風に作成していました。

f:id:kazuhironagai77:20200830204337p:plain

更にYouTubeUnreal Engine C++ Training Series - UENUMでUENUMの作成方法が説明されていました。

f:id:kazuhironagai77:20200830204412p:plain

このビデオによると純粋なc++の問題としてenumと宣言するのは古いやり方で、より安全に宣言するにはenum classとした方が良いらしいです。Cppreference.comのEnumeration declarationにこの二つの違いについての詳しい解説が載っていましたが、これを読んでいるとC++の勉強になってしますので止めます。ざっと見た感じでは普通に使用している限りは問題ないように思えます。それよりもこのビデオでuint8の方の意味も説明されていました。Uint8の場合、1 byte分、つまり255個?のenumeratorsが作成出来るみたいです。

こんな感じで作成しました。RPGGameModeBase.h内に作成しました。RPGGameModeBaseクラスで使用するので、手頃な場所でしょう。

f:id:kazuhironagai77:20200830204433p:plain

GRPGameModeBaseクラス内に変数も作成します。

f:id:kazuhironagai77:20200830204451p:plain

更に念のために初期化もしておきます。

f:id:kazuhironagai77:20200830204506p:plain

ビルドします。

f:id:kazuhironagai77:20200830204524p:plain

出来ました。

次にこの変数にBPからアクセス出来るか試してみます。

f:id:kazuhironagai77:20200830204541p:plain

道具屋の主人のボックス内にプレイヤーの操作するキャラが侵入したらGRPGameModeBaseクラス内の変数、myPlaceForEventsの値がPE_ItemShopに変更されます。逆にそのボックスから出る時はPE_Noneに戻ります。

f:id:kazuhironagai77:20200830204602p:plain

f:id:kazuhironagai77:20200830204619p:plain

出来ますね。

今度はボックス内にプレイヤーの操作するキャラがいる時はあるキーを押す事でイベントが発生する事にしましょう。

ボタンはdo somethingの意味でキーボードのdを押した時に発動する事にします。

まずCharacterクラス内のSetupPlayerInputComponent()関数内にBindAction()関数を追加します。

f:id:kazuhironagai77:20200830204635p:plain

そしてDoSomething()関数を作成します。

f:id:kazuhironagai77:20200830204708p:plain

と言ってもDoSomething()関数の実装はBPでするつもりなので宣言だけです。

これで上手く行くのでしょうか?取りあえずビルドします。

f:id:kazuhironagai77:20200830204725p:plain

ビルドは成功しましたので続行します。

InputのAction MappingsにDoSomethingを追加しDを選択します。

f:id:kazuhironagai77:20200830204748p:plain

ThirdPersonCharacterクラス内にDo Somethingの実装をしました。

f:id:kazuhironagai77:20200830204805p:plain

テストします。

Playボタンを押してゲームを開始し、Dを押すと

f:id:kazuhironagai77:20200830204823p:plain

ThirdPersonCharacterBP内に書いたDo Something()関数の実装部分が実行されました。

出来ているようですので次に進みます。

f:id:kazuhironagai77:20200830204840p:plain

最初のIsValid()関数は0でない限り承認してしまったような気もしますが取りあえずはこれでやってみます。

残りは、Level BPに書かれているのと全く同じです。

f:id:kazuhironagai77:20200830204855p:plain

テストします。

道具屋の主人のボックス内に侵入してDを押しました。

f:id:kazuhironagai77:20200830204916p:plain

普通にウィジェットが開かれています。問題無いみたいですね。

同様に武器屋の場合も作成します。

やり方は道具屋と全く同じなので省略します。

テストも成功しました。

今度はアイテムを拾う場合を実装します。

f:id:kazuhironagai77:20200830204935p:plain

スペルが間違っている。Droppedですね。直します。

f:id:kazuhironagai77:20200830204952p:plain

こっちも間違っていました。直しました。これはPathも直さないと駄目みたいです。

色々弄りました。多分直ったでしょう。

これだけ分かりません。DropedItemsフォルダーの名前をDroppedItemsに変更したらDropedItemsフォルダーとDroppedItemsフォルダーの2つフォルダーが作成されたのでDropedItemsフォルダーを消そうとしたら出て来ました。

f:id:kazuhironagai77:20200830205010p:plain

分からないので今は残しておきます。

変な所で時間を食ってしまいました。

PE_PickUpの先を実装します。

f:id:kazuhironagai77:20200830205027p:plain

基本的には同じです。DroppedItemBaseのインスタンスはRPGGameModeBaseBP内に新たに変数を作成してそこに保持する事にしました。それ以外はLevel BPで実装していた時と同じです。

後、ここも直しました。

f:id:kazuhironagai77:20200830205044p:plain

DroppedItemBaseのボックス内にプレイヤーの操作するキャラが侵入した時RPGGameModeBaseBPのDroppedItemContentにselfをセットするようにしました。

テストします。

f:id:kazuhironagai77:20200830205105p:plain

出来ているみたいです。

後はNPCの老人との会話だけです。

Level BPの丸コピーですが行けるでしょう。

f:id:kazuhironagai77:20200830205126p:plain

テストします。

f:id:kazuhironagai77:20200830205143p:plain

出来ました。

これで完成ですが、やはりDは押しにくいのでEに変更します。

Level BPのEを外して、

f:id:kazuhironagai77:20200830205208p:plain

Action MappingのDoSomethingをDからEに変更します。

f:id:kazuhironagai77:20200830205223p:plain

テストしたら正常に動きました。

要らない変数やコードを消します。

と思ったのですが一応念のために1週間検討してから消す事にします。Githubを利用していないので消すと取り返すが付かないのです。今は無料で非公開のGithubが利用出来るはずなので使った方が便利です。そろそろ使用を考えます。

4.まとめと感想

今週はこれで終わりです。

あまり関係ない話ですが、スクリーンショットを取るときshift + F11で撮影するんですが、そのスクリーンショット用のソフトを開くのを忘れてshift + F11を押してしまう事が良くあります。そうするとUE4EditorがTool Barの前に飛び出して来て非常に使いにくくなります。これがどうやっても元に戻す方法が分からなくて、こうなった時は一端エディターを閉じていたんですが最近その直し方が分かりました。なんともう一回、shift + F11を押せば良かったんです。

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 新しい機能を追加する

f:id:kazuhironagai77:20200823214016p:plain

<前文>

遂にアプリのショバ代戦争が始まりました。私はアメリカでアプリ開発者や小売り業者が自分たちのWebsiteで同じアプリや商品を安く売り始めているのがトレンドになっているのは聞いていたのと、アップ〇社の創設者が30%のショバ代はOSから全て作成している中で第三者にアプリを販売できる環境を提供している事から決して暴利ではないし、アプリの審査はユーザーの安全を保障するためのものでこれも決してアプリ開発業者を差別するためのものではない。と突然言い始めたのを聞いて、アプリのショバ代戦争の前兆は感じていましたが、まさかUE4を有するEpic Games社が先陣を切るとは思いませんでした。

アップ〇社の言い分は良く分かりますが、マイクロソフ〇社のOSとIEとネットスケー〇社の話を知ってしまうとウーンと思ってしまいますね。個人的にはこの裁判はepic gamesに勝ってほしいと思います。ただ公平に言えばアメリカの世論でもアップ〇を支持する人も多いです。私がいつも情報源にしている人達でもこの裁判をどう思うのかについては意見が割れています。基本的にプログラマーはEpic側、弁護士はアップ〇を支持しています。アップ〇で一度でも働いた事のあるプログラマーgoogleでは働けませんし逆もまたしかりなので、プログラマーにとってはこの二つの会社しか提供していない携帯電話のOSは完全な独占(duopoly)です。その上でそのOS上で動くアプリを提供するプラットホームは自分たち以外には絶対に許可しないとやっていたら、「マイクロソフ〇社もやっていいよね。でもマイクロソフ〇社がそれの何倍も緩い事をやろうとしたときあんたらなって言ったけ。」と言いたくなります。他の職業や消費者にとってはそんなのは関係ないでしょうが。

ただし、私はこれからのコロナ共生時代は携帯電話の価値が大きく下がると思っているんです。コロナ共生時代はテレワークが主力になると考えているからです。自宅でPCが使用出来き、かつ一日の大半を自宅で過ごす時代になったら、基本的に携帯は要らなくなるからです。

だから私はこのアプリのショバ代戦争でEpic Games社がどうにかなるような事は無いと思っています。

それよりもUE4のユーザーが考えなければならないのはどうすれば面白いゲームが作れるか?だと思います。私もやっとUE4の使い方を理解出来ましたが、どうしたら面白いゲームが作れるようになるのかは全く分かりません。結局ゲームってのは、娯楽ですから面白く無ければ駄目なんです。

そこでFall Guysですよ。先週このゲームの実況をずっと見てました。(関係ないですがvtuberも初めて見ました。)ゲームはやらない私ですが、見ているだけでも本当に楽しいゲームです。しかし何でこのゲームが楽しいのか良く分からないんです。みんなでワイワイやるのが楽しいでしょうか。となるとやっぱり次に勉強するのはMMOの作成方法ですかね。

それでは今週の勉強を始めます。

<本文>

一応先週で、今まで作成した全ての機能の追加は終了したはずです。

それで今週は全体を見直してどんな機能を追加するか考えていこうと思います。

f:id:kazuhironagai77:20200823214210p:plain

まず、スタート画面ですが、作り直す必要がありますね。

f:id:kazuhironagai77:20200823214225p:plain

プレイ画面ですが、ここにもウィジェットがほしいですね。

後、地面や草もきちんと作成したいです。

f:id:kazuhironagai77:20200823214241p:plain

後は敵との戦闘システムですか。

アイテムや宝箱を拾えるようにもしたいです。

まだまだ直したい事はいっぱいありますがこの辺から直していきます。

. 新しい機能の追加

1.1 スタート画面の作成

スタート画面を作成し直します。

f:id:kazuhironagai77:20200823214312p:plain

f:id:kazuhironagai77:20200823214319p:plain

f:id:kazuhironagai77:20200823214327p:plain

f:id:kazuhironagai77:20200823214334p:plain

取りあえずスタート画面はこんな感じです。

カメラの回転は、新しいアクターを作成してそれに管理させました。

f:id:kazuhironagai77:20200823214353p:plain

f:id:kazuhironagai77:20200823214359p:plain

f:id:kazuhironagai77:20200823214406p:plain

そのクラスのインスタンスをlevel BPから作成して使用するカメラとしてSetViewTargetwithBlend関数にセットします。

f:id:kazuhironagai77:20200823214453p:plain

特に新しい事はしていませんので残りの工程は省略します。

Play画面にウィジェットを追加して簡単な操作が出来るようにしようと思いましたが、そうすると常にマウスのカーソルを表示する必要があります。これはちょっと考える必要がありそうですので今回はパスします。

Level内のマップのデザインですが、デザインをどこまで自分で勉強するかはまだ考え中なのでこれも今回はパスします。

1.2  落ちているアイテムを拾う

もう大体、UE4の機能も大体理解して来たので自分で考えて作成してみます。

出来ました。

まず結果から示します。

f:id:kazuhironagai77:20200823214515p:plain

アイテムは3Dモデルがまだなかったので取りあえず武器だけ作成しました。

上のスクリーンショットに示したように木の盾(小)と短剣(小)が落ちています。

短剣(小)に近づいてEを押すと以下のUIが表示されます。

f:id:kazuhironagai77:20200823214532p:plain

「拾う」をクリックすると

f:id:kazuhironagai77:20200823214547p:plain

短剣(小)の3Dイメージが消えて

f:id:kazuhironagai77:20200823214602p:plain

装備品に短剣(小)が追加されます。

こんな感じで作成しました。

まずDropItemBaseクラスを作成します。

f:id:kazuhironagai77:20200823214618p:plain

マップ上にこのクラスのインスタンスを、拾えるアイテムとして配置します。そのためには、

f:id:kazuhironagai77:20200823214635p:plain

f:id:kazuhironagai77:20200823214641p:plain

3Dアイテムを表示するためのStaticMeshとキャラが近づいてきた事を知らせるBoxのtriggerを追加します。

更に、以下に示した3つの変数を追加します。

f:id:kazuhironagai77:20200823214658p:plain

RPGGameInstanceにアイテムを拾うために必要な幾つかの変数を追加しました。(後で説明します。)のでMyGameInstanceでassignする必要があります。Name変数はアイテムの名前です。IsWeaponはこのアイテムが武器か道具かを示すためのBooleanです。

f:id:kazuhironagai77:20200823214715p:plain

このクラスのインスタンスが作成されたらEvent BeginPlayで直ぐにNameからMeshを作成し、それをStaticMeshにセットします。

f:id:kazuhironagai77:20200823214734p:plain

関数、ReturnStaticMeshOfItemsは上記に示した実装をしています。これで武器の名前から該当する3Dモデルを返します。

このインスタンスのボックス内でEを押すと以下のlevel内に実装されたコードからPickUpItemWIdgetが呼ばれます。

f:id:kazuhironagai77:20200823214752p:plain

基本的に全てのユーザーからのインプットはThirdPersonCharacterクラスが管理するはずなのですが、何故かLevel BPで管理されています。後で直します。

以下にPickupItemウィジェットを示します。

f:id:kazuhironagai77:20200823214808p:plain

実装するに当たって特に新しい事はしませんでした。ので実装部は省略します。

課題を以下に示します。

DropItemBaseのインスタンスを置く場合、ボックスが重ならない様に設置する必要があります。

f:id:kazuhironagai77:20200823214825p:plain

重なるとたまに変な挙動を示す事があります。

以上です。

あまりうまく説明出来ませんね。次回からは、やりながらまとめる事にします。きちんと完成するか不安だったので取りあえずやってみたらブログに記録するのをすっかり忘れて終りまで進んでしまいました。

宝箱とアイテムは3Dモデルがないので後で作成します。

1.3  NPC(村人)との会話

武器屋や道具屋の主人との会話は出来ましたが単なる村人との会話システムはまだ作っていませんでした。

これは、基本的には武器屋や道具屋の主人との会話の簡易版でいいはずです。道具屋の主人をどうやって作成したのか忘れてしまったのでその復習から始めます。

Characterクラスから作成していますね。

f:id:kazuhironagai77:20200823214858p:plain

中を見てみます。

f:id:kazuhironagai77:20200823214916p:plain

f:id:kazuhironagai77:20200823214922p:plain

うーん。ボックスぐらいですかね。特に追加してあるのは。

f:id:kazuhironagai77:20200823214938p:plain

当然ですが、ボックス内にプレイヤーの操作するキャラが入った時にeventが発動します。

f:id:kazuhironagai77:20200823214954p:plain

正し、RPGGameInstanceBPのTalkShop変数の値を変更しているだけですね。

ここでTalkShop変数がTrueになるとプレイヤーがEを押した時にイベントが始まります。勿論、私はlevel BP内にその事を実装したと覚えていますからlevel BPを開きますが、本当ならThirdPersonCharacterに実装すべきですね。

f:id:kazuhironagai77:20200823215010p:plain

WidgetのShopWelcomeを開いているだけですね。

f:id:kazuhironagai77:20200823215027p:plain

これを見るとShopWelcomeウィジェットの親クラスはNPC_Parentですね。どんなウィジェットだったのか覚えていません。見てみます。

f:id:kazuhironagai77:20200823215044p:plain

何これ、なんもないじゃん。

f:id:kazuhironagai77:20200823215108p:plain

思い出しました。ここでNPCのセリフを一括管理しているんでした。

f:id:kazuhironagai77:20200823215124p:plain

後、このTextの配列(array)をduplicateするとshallowコピーになるのか知りませんが、子クラスからその配列が参照出来なくなるんでした。

うん。作り方は分かりました。

まず村人を作成します。

f:id:kazuhironagai77:20200823215140p:plain

NPC_ItemShopOwnerkからduplicateしました。

f:id:kazuhironagai77:20200823215153p:plain

RPGGameInstanceクラスにあるTalkShop変数の代わりになる変数を作成するのですが、この方法で管理すると50人NPCを作成したら50回UE4C++のRPGGameInstanceクラスを書き直して一々buildしなければならなくなります。ちょっと管理方法を考えます。今回はRPGGameInstanceBPクラスに作成する事にします。

f:id:kazuhironagai77:20200823215211p:plain

f:id:kazuhironagai77:20200823215220p:plain

今度はLevel BP内から

f:id:kazuhironagai77:20200823215240p:plain

その村人と会話する場合に開くWidgetを指定します。

f:id:kazuhironagai77:20200823215318p:plain

Level BPで管理している事を差し置いてももうグダグダになっています。上から道具屋、武器屋、アイテムを拾う場合、そして村人との会話です。後でSwitchをつかって綺麗に書き直します。

NPC_Parentに村人用のdialogを作成します。

f:id:kazuhironagai77:20200823215336p:plain

f:id:kazuhironagai77:20200823215342p:plain

子クラス、Oldman_Welcomeを作成します。

f:id:kazuhironagai77:20200823215358p:plain

f:id:kazuhironagai77:20200823215405p:plain

Level BPからこのウィジェットを作成します。

f:id:kazuhironagai77:20200823215421p:plain

テストします。

f:id:kazuhironagai77:20200823215436p:plain

出来ました。

1.4  ナレーション用のウィジェット

会話だけでなくナレーション用のウィジェットも一つほしいですね。作ります。

出来ました。やり方は今までと同じなので特に記録する必要はないと思い省きました。

f:id:kazuhironagai77:20200823215503p:plain

以下に示したように、Box内にプレイヤーが操作するキャラが侵入するといきなり表示されます。

f:id:kazuhironagai77:20200823215527p:plain

2. 今後の展開

現在作成しているRPGは沢山の機能が追加されましたが、ゲームとしてはまだ足りない部分が沢山あります。ただしどの部分が足りないのかが把握していません。どうしたら良いでしょうか。ゲームとして完成させるのが足りない部分を把握する一番の近道かもしれません。ので今後は、実際にプレイ出来るゲームとして足りない部分を追加する事にします。

ただし、ここで大きな問題があります。それはアートの部分です。私はプログラマーで3Dモデルや音楽を作成する能力はありませんので、その辺が必要な時にどうするか決めておく必要があります。

3Dモデル、音楽、ストーリーの3つの分野についてどうするか以下にまとめました。

2.1 3Dモデル

単純に3Dモデルと言いましたが以下の分野を総合して言っています。

2.1.1 Level デザイン

街や村、迷宮や城から、草原、森、沼地などの作成を総合しています。PostProcessingもここに含める事にします。

2.1.2 キャラクターやモンスターの3Dモデルやそのアニメーション

現状は無料でもらった3Dモデルと付属のアニメーションを使用しています。基本的に今は足りていますが、村人などのNPCはいません。3Dモデルの作成は勉強したい分野でかつBlenderを使用すれば無料で出来るので時間が許されれば自作したいです。マテリアルの作成もここに含まれます。

2.1.3 物の作成

ここで言う物とは本や巻物、ランプなどから木や家などを含みます。基本的にLevelデザインで配置するそれぞれのユニットの作成です。2.1.2 のキャラクターとの違いはrigがない事です。

2.1.4 魔法などのエフェクト

これはNiagara systemもそろそろ勉強しないといけないので勉強します。

これ以外もあるかもしれませんが今思いついたのを書き出しました。

2.2 ストーリーはどうするのか?

読書家な私としてはストーリーは自分で考えたいですが、それに拘ってUE4の勉強がおろそかになる事は避けたいです。

2.3 音楽はどうするのか?

ここだけははっきりしています。私は音楽に全く興味がないです。市販のものか無料で商業利用可能なものを適当に追加します。

3.まとめと感想

今週はこれだけです。

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 前のプロジェクトで自作した機能を追加する3

 

f:id:kazuhironagai77:20200816211803p:plain

<前文>

戦わないから無敵な人

今週はプレイした事もないのにlast of ○○2についての批判に対する考察を書こうと思っていたのですが、もっとムカつく事件があったのでそっちを書く事にします。あんまり詳しく書いてしまうと個人攻撃になってしまうので、ある程度ぼかして書きますが、簡単に言うと私がBlack lives matterと言った時に「Black lifes matterが正しい。」とご丁寧に指導してくれる人がおりました。その人があんまり堂々と指摘するので私も、えっと思いつつその時は「間違えていました。」と言ってしまいました。後から気になって調べたら、やっぱりlivesであってました。私は何で自分が間違っていると認めてしまったのか、本当に色々な意味でムカつく事件でした。

一番悪いのはその場でどっちが正しいかを調べなかった私ですが、その人もあんまりにも堂々とし過ぎているのも問題だと思うんです。これmy name is…事件の時もあったんですが、指摘する人があんまりにも堂々としていると明らかに間違っているにもかかわらず、こっちが間違っている気になってしまいます。だから何でそんなに堂々と出来るか考えてみたんですが、そういうタイプの人に共通するあるものを発見しました。そのタイプは絶対、自分では英語を話さないんです。話さないし書きもしない。だから一度も英語を間違えた事もないんです。人生で一度も英語を間違えた事もないんですよ。そりゃ堂々としますよ。

戦わないから無敵な人と同じなんです。

私は最初、この「戦わないから無敵な人」はどこかで有効に活用できるかもしれないと期待しました。でもそれは無理だと直ぐに分かりました。コードを書かなければバグを作ったことのないプログラマーになれます。でもそんな奴に一銭の価値もありませんよ。プログラマーは実際にコードを書いて、そのコードのバグを自分で直す事で成長していくんです。

外国語をネイティブと全く同じにしゃべる人達

全く日本人と同じ日本語をしゃべるアメリカ人と会いました。その人は大人になってから日本語を勉強したそうですが、全く日本人と同じ日本語をしゃべります。その人曰く、最初はこんなに上手くしゃべれなかったそうです。ある日、道端で黒人にお前の日本語ここが間違っていると指摘されて、凄い頭に来てその黒人のしゃべっている日本語を録音して大学にいる日本人に聞かせたそうです。そしたらその録音を聞いた全ての日本人がこれは日本人がしゃべっている。文法的な間違いや日本人が言わない言い回しが一個もない。さらに発音も完璧であると。それでその人もう一度その黒人にあって話を聞いたら、別に子供の時に日本で育ったわけでもなく日本語は独学で勉強したと言ったそうです。ただしその黒人が言った学習方法が非常に独特でそれまで聞いた事がないやり方だったそうです。

その人は非常に強いショックを受けたのですが、その学習方法を信じるまでにはいかなかったのでその時は実行しなかったそうです。それから何年かして英語を完璧に話すポルトガル人(ポーランド人だったかも?)にあった時に、そのポルトガル人の英語の学習方法がその黒人が言った日本語の学習方法と全く同じだったそうです。それでもう大学で教わった日本語は全部忘れてそのやり方で一から学習し直したそうです。そしたら2年位で日本人と全く区別つかない日本語をしゃべれるようになったそうです。

ちょっと眉唾ですが気になる話ではあります。因みに眉唾の事を英語でひとつまみの塩(a grain of salt)と言います。私この二つがごっちゃになって眉に塩塗って聞いて下さいと言った事があります。

その学習方法は以下の通りです。

  • まず発音を完璧にする。
  • その言語を聞きまくる。24時間、ひたすらその言語付けの環境で過ごす(英語なら海外ドラマやハリウッド映画を見まくる。日本語ならアニメを見るなど)。意味が分からないフレーズや単語はその言語の辞書で調べまくる。文法は意味の分からない文を理解するために使用する。決して文法から文を作成しようとしてはいけない。単語を覚える時は例文事覚える。
  • ある日、突然その言語で夢を見たり、その言語で独り言を口走しったりするようになる。この段階になって初めてしゃべったり書いたりする練習を始める。ただし3文に一個以上文法上のミスがある場合は、しゃべる練習はまだ早く、2の段階をもっとやるか、短い文を文法上の間違いが全くない状態まで推敲する練習をする。

これだけだそうです。この人の主張で特に独特だったのが「文法から作文すると必ず文法を間違える。」でした。文法は意味が理解出来ない文を理解する時に必要であるが、しゃべるときに文法に基づいて作文すると必ず変な文になる。でした。じゃどうするんだと言うと、2番の勉強が重要だそうです。ここでひたすらその言語の環境に自分を浸す事で、脳が勝手に正しい文を作成してくれるようになるそうです。ひたすらその言語に浸る事で何となくこれが正しい言い方というのを脳が構築出来る様になるというのです。

言われてみるとこれって正しいですね。さっきのBlack Lives Matterだって私は何となくそんな言い方が正しいような気がすると思って言った訳で文法を考えて言ったわけじゃないです。だから文法間違ってますよと突っ込まれたら、エッとなって誤ってしまった訳ですが、結局は私の言い方が正しかったわけです。

うーん。

条件付きながらかなり納得出来る話です。

まあこの話が絶対正しいかどうかは置いておいて、外国語をネイティブと全く同じレベルで修得する学習法というか外国語学習の正解みたいなのはありそうな気がします。

それでは今週の勉強を始めます。

<本文>

今週は最後の大きな機能、装備した武器を実際の3Dモデルに装着する部分を行います。前回どうやったのか全く覚えていないのでまず復習からやっていきます。

1.機能の追加

1.1 ブログ(2月23日)の追加

まず、この週のブログをざっと読んでどんな方法で武器をキャラに付加しているのかを復習しました。

はっきりとは覚えていないのですが、この週のブログで武器の3Dモデルを付加するためのソケットの位置と角度を大幅に変更したのは間違いで、

f:id:kazuhironagai77:20200816211920p:plain

別に用意されている武器を持った状態のアニメーションを最終的に使用した気がします。

実際のCh2 でのコードは以下のようになっています。

Weaponウィジェットクラス内で実装されています。

f:id:kazuhironagai77:20200816211948p:plain

FieldPlayerのEventBeginPlayで以下の実装がされているんですが、別なレベルにワープした時これで武器が装備出来るのでしょうか?ちょっと良く分かりません。

f:id:kazuhironagai77:20200816212010p:plain

アニメーションの方は一端置いておいて武器が装着されるようにします。

以下に示した方法で、武器が装備した時に武器の3Dイメージがキャラに装着されるようにしました。

最初にBaseWeaponをStaticMeshActorクラスから派生して作成します。

f:id:kazuhironagai77:20200816212043p:plain

MobilityをMovableにセットします。

f:id:kazuhironagai77:20200816212105p:plain

セットした武器がキャラクターの体などに当たると変な挙動を示すのでNoCollisionに設置します。(後で変更するかもしれません。)

f:id:kazuhironagai77:20200816212134p:plain

StaticMeshにはSword01SMをセットしましたが、本当はしなくてもいいはずです。

f:id:kazuhironagai77:20200816212154p:plain

このBaseWeaponクラスを元にそれぞれの武器の3Dイメージを保持するクラスを作成します。

f:id:kazuhironagai77:20200816212221p:plain

今回は試しなので一個だけ作成しました。

今度は、Weaponウィジェット内で武器を装備するためにボタンをクリックした時、実行されるコードを追加します。

f:id:kazuhironagai77:20200816212248p:plain

関数Ruturn Weapon Classでは先程作成したShortSwordSmallクラスを返します。

f:id:kazuhironagai77:20200816212313p:plain

ここで作成したインスタンスは、後でThirdPersonCharacterからアクセスする必要が出てくるのでThirdPersonCharacterクラス内に変数BaseWeaponをBaseWeaponクラスから作成し、それにassignしておきます。

f:id:kazuhironagai77:20200816212342p:plain

f:id:kazuhironagai77:20200816212350p:plain

更にアニメーションを武器持ちのヤツに変更します。

f:id:kazuhironagai77:20200816212532p:plain

テストします。

f:id:kazuhironagai77:20200816212625p:plain

こんな感じに成りました。中々いいですね。

今度は武器を外せるようにします。

この週に載っていると同じやり方で行いました。

f:id:kazuhironagai77:20200816212657p:plain

DestroyActorを使用して武器のアクターを破壊します。その後キャラのモーションを素手のヤツに変更します。

テストします。

f:id:kazuhironagai77:20200816212723p:plain

元に戻りました。

今度は防具の装備を行います。

この週のブログではStaticMeshActorからBaseWeaponを作成したようにStaticMeshActorからBaseArmorを作成しましたが、BaseArmorの代わりにBaseWeaponクラスをそのまま使用しても大丈夫な気がします。ので今回はBaseWeaponクラスからそれぞれのarmorのアクターを作成してみます。

f:id:kazuhironagai77:20200816212751p:plain

これをweaponクラスで装備します。

f:id:kazuhironagai77:20200816212820p:plain

キャラの左手に追加するようにしました。

テストします。

f:id:kazuhironagai77:20200816212848p:plain

f:id:kazuhironagai77:20200816212856p:plain

今度は防具を外せるようにします。

f:id:kazuhironagai77:20200816212914p:plain

f:id:kazuhironagai77:20200816212922p:plain

外せました。

f:id:kazuhironagai77:20200816212957p:plain

武器と防具を装備した時で防具だけ外しました。モーションは武器を装備した時のままです。

今度は色々な武器を装備出来る様にします。

f:id:kazuhironagai77:20200816213112p:plain

f:id:kazuhironagai77:20200816213120p:plain

武器を装備した状態で別の武器を装備するとBaseWeaponのインスタンスが複数作成されるので、既に作成されているBaseWeaponのインスタンスを破壊します。

f:id:kazuhironagai77:20200816213146p:plain

結果を以下に示します。

f:id:kazuhironagai77:20200816213231p:plain

f:id:kazuhironagai77:20200816213240p:plain

f:id:kazuhironagai77:20200816213250p:plain

f:id:kazuhironagai77:20200816213303p:plain

今度は防具を作成します。

f:id:kazuhironagai77:20200816213323p:plain

f:id:kazuhironagai77:20200816213332p:plain

f:id:kazuhironagai77:20200816213343p:plain

結果です。

f:id:kazuhironagai77:20200816213404p:plain

f:id:kazuhironagai77:20200816213413p:plain

f:id:kazuhironagai77:20200816213422p:plain

剣も持つとこんな感じになります。

f:id:kazuhironagai77:20200816213444p:plain

最後にワープしても武器と防具を装備しているようにします。

f:id:kazuhironagai77:20200816213502p:plain

f:id:kazuhironagai77:20200816213510p:plain

テストします。

f:id:kazuhironagai77:20200816213526p:plain

出来ました。

. まとめと感想

今週はこれだけです。

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 前のプロジェクトで自作した機能を追加する2

f:id:kazuhironagai77:20200809232024p:plain

<前文>

作ったゲームは売れるのか?

ここまで勉強して作成したゲームが売れなかったらどうしよう。と心配になっています。と言うか売れないような予感がします。英語の発音の区別が付くゲームはもう大体完成しているのですが、こっちは成果が凄い(30分位やるとLとRの区別がはっきりつく)のでこっちは売れそうな気がします。

ポケモンgoをやっていた時は電子データにこんなに価値があるのかと思いましたが、飽きたらどうでも良くなってしまいました。普段ゲームをしない私はゲームそのものに価値を見出せないんです。元々、3D graphicsの勉強としてUE4を勉強していたので3D graphicsから離れる気はないのですが、ゲームそのものは元々どうでも良いんです。

しかしここまで勉強した以上、商品として金銭と交換できる価値のあるものに仕上げたいです。しかし何を追加したら価値が生まれるのでしょうか?全然分かりません。MMOとかにすればいいのでしょうか?

そう言えば、AAAのゲームでもユーザーから嫌われて全然売れないゲームがありますね。ゲームを作成するのは結構な博打ですね。沢山作って売れたので元とるみたいな商法は出来ないですかね。マンガだって売れるかどうか分からないじゃないですか?沢山作成して結果売れたのが正解みたいな所があるじゃないですか。

ここでLast of ○○についての感想に対しての私見を述べようと思ったのですが、まだ自分の中でまとまっていません。ので来週書く事にします。

まだやる事は残っているので今週も勉強を始めます。

<本文>

今週も前のプロジェクトに追加した機能をch4_3に追加していきます。

1.機能の追加

1.1  ブログ(2月9日)の追加

この週のブログはこれまでのバグの直しを行っています。同じ様にやります。

1.1.1 同じ武器が何個も買える

試したら買えました。

f:id:kazuhironagai77:20200809232144p:plain

ブログでは同じ値段で売れるようにする事で解決しています。同じようにします。

出来ました。思ったより難しかったです。

以下にWeaponウィジェット内の武器を売るためのコードを示します。

f:id:kazuhironagai77:20200809232211p:plain

テストします。

まず短剣(小)と短剣(大)を購入しました。

f:id:kazuhironagai77:20200809232233p:plain

両方売ります。

f:id:kazuhironagai77:20200809232258p:plain

所持していた武器の記録が消えその代り、金貨が100になりました。

この週のブログに抱えている通り、武器を装備したままその武器を売ると、武器が無くなったにも関わらず装備したままになります。これは後で直します。

1.1.2 ワープすると購入した装備品が消えてしまう

これは消えないと思いますが試してみます。

f:id:kazuhironagai77:20200809232337p:plain

ワープしても装備品は消えません。出来ています。

1.1.3 盾なのに武器に装備されている。

試してみます。

f:id:kazuhironagai77:20200809232412p:plain

されています。直します。

f:id:kazuhironagai77:20200809232434p:plain

武器のタイプがweaponの時だけ装備出来るようにしました。この週のブログに防具の装備は後で作るとあるのでここでも同じようにします。

一応テストします。

f:id:kazuhironagai77:20200809232450p:plain

防具である盾は装備出来ません。

1.1. 武器の名称がボタンに被っている場合がある。

前に武器の名前を短くする事で解決したような気がします。その時の名前をそのまま引き継いでるはずなのではみ出したりはしないはずですが、一応確認します。

f:id:kazuhironagai77:20200809232528p:plain

一番長い名前の魔法の杖でもはみ出して表示される事はないので大丈夫そうです。

1.1. 5 Healerの状態表示がそのまま残っています。

これは完全に消してあります。

1.1.6 武器のイラストがない。

イラスト自体は追加してありますがマウスのカーソルを合わせてもイラストは表示されません。これを直しましょう。

f:id:kazuhironagai77:20200809232614p:plain

出来ました。

武器を売った時だけイメージが消えないのでそれを直します。

f:id:kazuhironagai77:20200809232639p:plain

テストします。

f:id:kazuhironagai77:20200809232656p:plain

直りました。

1.1.7 装備品の値段が分からない。

これも直します。

f:id:kazuhironagai77:20200809232756p:plain

出来ました。

組んだコードは下に示します。

f:id:kazuhironagai77:20200809232827p:plain

1.1.8 装備した時に今より何が強くなるのか不明。

この時のブログでは、どのように基礎ATK(武器を装備していない時にATK)を管理すべきかが決定していないので、云々と書かれていて直していません。

f:id:kazuhironagai77:20200809232857p:plain

装備画面での武器の表示を確認して終です。

装備画面で武器の値段を表示する必要はないですが、表示されています。

1.1.9 デザインの改善

武器の返品が可能ならデザインの変更が要らないのでは?と言う考察だけでした。

1.2 ブログ(2月16日)の追加

どんどんやって行きます。

1.2.1 ATKの値をGameCharacterクラスのATKで管理するのかFieldPlayerのSoldierbaseAtkするのか?

色々やっていますが、結局は、武器攻撃力と基礎攻撃力を足した総合的な攻撃力をGameCharacterのATKに保持させ、装備している武器名をGameCharacterのWeaponEquippedに保持させる事で結果的に基礎攻撃力も管理できると言う事です。だからThirdPersonCharacterのSoldierbaseAtkは要らないはずです。何かの計算、例えば武器を外した時やレベルが上がった時の計算を簡単にするためにThirdPersonCharacterのSoldierbaseAtkは使用されるだけです。

ここで問題にされているのは、レベルが上がった時のATKと武器を外した時のATKが正しく計算されているかどうかです。これを検討するためには武器を外す機能が必要ですがそれはまだ作成していません。

武器を外す機能は次の節で作成しているみたいなのでそっちを先にします。

1.2.2 素手を武具にしています。装備を外すボタンを作成して素手を武具から外します。

以下に示したように作成しました。

f:id:kazuhironagai77:20200809233008p:plain

f:id:kazuhironagai77:20200809233021p:plain

テストします。

f:id:kazuhironagai77:20200809233048p:plain

外すを押しました。

f:id:kazuhironagai77:20200809233106p:plain

攻撃値が下がり武器の表示が消えました。

この後色々テストしましたが、問題は出ませんでしたので前の問題に戻ります。

1.2.3 ATKの値もう一度

よくよく考えたら武器を外した時は前節で作成していました。レベルが上がった時のATKの計算を直します。色々考えましたがSoldierbaseAtkは計算しやすくするためにはやっぱり絶対必要です。ThirdPersonCharacterに設置するのがベストかどうかが不明ですがもうそこに作成しちゃったのでそれを利用する事にします。

結局、大まかなやり方は前回と同じになりました。以下に簡単に説明します。

UE4C++のRPGGameModeBaseに以下の関数を作成します。

f:id:kazuhironagai77:20200809233143p:plain

この関数はBlueprintImplementableEventを指定しているので実装はBP内で行います。

更にこの関数を実行する時は、

f:id:kazuhironagai77:20200809233207p:plain

キャラのレベルが上がった時です。

BP内での実装は、以下の通りです。

f:id:kazuhironagai77:20200809233243p:plain

テストします。

f:id:kazuhironagai77:20200809233300p:plain

短剣(小)を装備した状態で敵を倒しレベルが上がりました。レベルが上がったので攻撃値が1上がり61になっています。

武器を外します。

f:id:kazuhironagai77:20200809233318p:plain

武器を外しても攻撃値は1上がったままでいます。

1.2.4 装備している武具を売る事が出来ます。

実装方法を読んだら結構上手い方法でやっていました。正直感心しました。同じ方法でやります。

f:id:kazuhironagai77:20200809233354p:plain

テストします。

f:id:kazuhironagai77:20200809233412p:plain

出来ていました。

1.2.5 防具の装備

武器の装備をもう一回やり直しとか書いています。知ってたら武器の装備を作成した時に一緒に防具の装備も作成していました。

はあ。

やるしかないですね。

出来ました。結果だけ下に示します。

f:id:kazuhironagai77:20200809233450p:plain

防具を装備します。

f:id:kazuhironagai77:20200809233506p:plain

木の盾(小)を装備すると防御値が10上がり50に成りました。

今度は木の盾(大)を装備します。

f:id:kazuhironagai77:20200809233526p:plain

防御値が20上がり60に成りました。

「防具を外す」を押します。

f:id:kazuhironagai77:20200809233559p:plain

素の防御値である40に戻りました。

今度はレベルが上がった場合を調べます。

f:id:kazuhironagai77:20200809233618p:plain

木の盾(小)から木の盾(大)に交換します。

f:id:kazuhironagai77:20200809233644p:plain

レベルが上がった時に41となった基礎防御値は、防具を交換しても41のままのようです。

今度は防具を外してみます。

f:id:kazuhironagai77:20200809233704p:plain

防具を外した場合も、基礎防御値は41のままです。

今度は木の盾(小)を装備したままワープしてみます。

f:id:kazuhironagai77:20200809233729p:plain

ワープをしても基礎防御値は41のままです。大丈夫みたいですね。

今度は防具を売ってみます。

f:id:kazuhironagai77:20200809233751p:plain

装備している防具も赤く表示され売る事が出来ません。出来てるみたいです。

1.2.6 装備した時に今より何が強くなるのか不明

f:id:kazuhironagai77:20200809233825p:plain

これを追加すれば良いみたいです。

f:id:kazuhironagai77:20200809233842p:plain

出来ました。

1.2.7 デザインの改善

ポーズ画面を以下のようにしました。

f:id:kazuhironagai77:20200809233934p:plain

ボタンを選択した場合は、以下の様にボタンの色が変わります。

f:id:kazuhironagai77:20200809233959p:plain

金貨の量が増えた場合、はみ出してしまうかもしれません。後で直します。

道具屋でアイテムを買う場合のUIです。

f:id:kazuhironagai77:20200809234019p:plain

アイテムの効果や値段が表示されるべきですね。現在どんな道具を所持しているのかも不明です。キャラの現在の状態も表示されるべきです。

残りのUIも同じ様な図柄に変更しました。

2.まとめと感想

今週はここまです。時間が無くて結構大変でした。

 

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 前のプロジェクトで自作した機能を追加する

f:id:kazuhironagai77:20200802215539p:plain

<前文>

もう中国とアメリカが戦争するのは避けられないPhaseに入ったなと思うのは私だけじゃないみたいで、ネットでもそこかしこに呟いている人がいるみたいです。トータルで10年アメリカに住んでいた私はかなりのアメリカの事情に通じていますが、そんな私は、今度の戦争はアメリカが負けるんじゃないかと言う気がしてかなり心配しています。私はアメリカにいる中国人を介してしか中国を知りませんから、中国が単なる張りぼての虎なのか実際凄いのかは分かりません。だから実際の中国は滅茶苦茶弱くて全く問題なかった。と言う可能性も勿論あります。しかしアメリカに限って言えば問題山積みで、BLMや新型コロ〇の対応を見ても「日本よりマシなのか?」と言う感じでひょっとするとベトナム戦争以上の泥沼化するとんでもない事態になるかもしれません。

正しComputer Scienceの分野に関してはアメリカの大学は依然として世界のトップを独走してますので留学する価値は断然あります。何事もリスクを取らなければ利益は得る事は出来ないのも真実で、これからの日本人は大局観を持たないと生きていけない時代になったのだと腹を括るしかないですね。

そう言えばアメリカ人のプログラマーが大学でComputer関連を勉強したい人向けにしたアドバイスで中々素晴らしいなと思ったのが2つほどあったのでそれを紹介します。アメリカの大学でcomputer scienceを勉強するために留学を考えてる高校生が私のこのブログを読んでいる可能性は0かもしれませんが、かなり含蓄を含んでいるアドバイスで、誰にでも参考になる内容でもあります。

最初のアドバイスはComputer science+別のメジャーのダブルメジャーの進めです。アメリカではプログラマーは花形中の花形の職業で競争が滅茶苦茶激しいです。他の学部なら奨学金が貰えた学生でもComputer scienceに専攻を変えたら成績が真ん中になるなんでザラです。そんな中で勝ち抜いた一握りの人だけが、Googleのような企業に就職出来る訳で大変な競争率な訳です。更に今、アメリカで話題になっているビザの問題も海外から留学した学生の場合は考えないといけません。これはアメリカ人の上司が外国人の部下の成果を奪うためにワザとビザの申請を忘れてアメリカから追い出す事です。何故これが明らかになったかというとフェイス〇ックで中国人の従業員がビザの申請がされていないのでアメリカから出国しなければならない事を知ってその場で飛び降り自殺した事件があったからです。(私が中国とアメリカの戦争が避けられないと思っているのはこういう事件がアメリカ中で起こっているからでもあります。)

こんな過当競争の中に身を置くより、ダブルメジャーになって他の分野でプログラマーとしてやって行く方が仕事もあるし収入も実際は安定しているらしいです。Computer scienceで上位の成績を維持できる生徒ならダブルメジャーも簡単ですし。実際、私は化学とcomputer scienceのダブルメジャーだったですがこんな経験もしています。ある物理化学の研究室で実験で得たスペクトラムキャリブレーション用のスペクトラムを比較するのに、それまでは1枚は水に濡らして窓ガラスに貼ってもう1枚を窓ガラスの反対側から重ねて一致する点を探していたのを、私が同じ事をパソコン上で出来るソフトを作成したら、その研究室のみんなから、パソコンに関する質問を山のように受けました。そのほとんどはExcelのデータの上下を逆にしたいがやり方が分からないみたいなパソコンの大先生でも解決出来るような内容で1日もかからずに解決したのですが、その後、その研究室のメンバーからの強烈な支持を受けました。彼らは元々量子化学の専門家なのでパソコンの専門家でいる必要がないんです。だからパソコンの専門家として別人を推薦しても自分の仕事が無くなる可能性が全くないのでいくらでもポジティブな推薦をしてくれるのです。その後、理論量子化学の研究室(こっちは1日中パソコン使って量子化学の計算をしているので化学者の間ではパソコンの専門家と思われている。)から意地悪されたのと、Computer scienceの3d graphicsの研究室に入れる事が決まったので化学とは疎遠になってしまいましたが、ダブルメジャーならパソコン関連の専門家として重宝されるのは間違いないです。

もう一つは「コンテンツクリエーターになる。」です。ひと昔前は、優れたソフトを開発すればすぐに売れたのですが、今はそれよりも誰が使っているかが重要になっているそうです。SNSで有名な人が使っているソフトは直ぐに何十万もダウンロードされますが、そのソフトより優れた機能があっても有名な人が使わないソフトは誰もダウンロードしないそうです。更に自分が有名なコンテンツクリエーターになれば、作成したソフトウェアは勝手に大量にダウンロードされるようになるらしいです。だからプログラマーと言えども今までのように裏方に回っていれば良いのではなく、真剣にコンテンツクリエーターとして自分を売り出す必要があるとの事です。

この意見は、半分だけ正解な気もします。最も人気が出るコンテンツはYouTubeでも高校生向けのコンテンツだからです。これは視聴者の知識と知性の平均が見事に高校生のそれとマッチしているからです。だから人気がある事と正しい事は必ずしも一致しないとも言えます。しかし有名なコンテンツクリエーターの存在は、ソフトの性能以上に重要な要素である事もまた事実で、もし有名なコンテンツクリエーターになれるのならダブルメジャーになるより遥かに効果があるでしょう。

それでは今週の勉強を始めます。

<本文>

ブログを見直すと去年の10月頃から新しい機能を追加していました。そんな昔からやっていたのかと結構ショックでした。このブログからです。そして3月1日のこのブログが最後です。数えてみたらその間に16回ブログを書いていました。流石に16回分のブログをここでやり直したら、更に4カ月かかってしまいます。

どうしようかな?

取りあえず今週はそのままやってみます。

1.自作した機能を今回のプロジェクトに追加する

1.1  10月24日のブログの内容を追加する。

ブログを読んでみると、この週では3つのレベルを自作してそれぞれのレベルに地図からワープ出来るような機能を作成しています。Fast Travel Within A single Level and Multiple Levels - (UE4)をそのまま使用して作成しています。その他にSetInputModeGameAndUI()BP関数とSetInputModeGameOnly()BP関数についての考察を行っていて自分で書いておいてアレなんですが結構興味深い内容でした。

まず、Fast Travel Within A single Level and Multiple Levels - (UE4)のワープするマップを追加します。

流石に前回のマップは適当すぎるのでまた作り直しました。ボタンは前回作成したものをそのまま使用します。

f:id:kazuhironagai77:20200802215701p:plain

2つのenum、Mapとzoneも作成しました。

f:id:kazuhironagai77:20200802215725p:plain

ここでチュートリアルはlandScaleを作成しますが、このプロジェクトには作成しません。

このチュートリアルではLighting need to be rebuiltが表示されているので以下の事をして消しています。

Light source とSkyLightのMobilityをMovableにセットする。

f:id:kazuhironagai77:20200802215757p:plain

前回、この部分はスキップしたのですが、この方法を採用するとLightingのrebuilt をしなくて良くなるそうです。なんでなんでしょうか?後で調べます。

Mapをコピーしてmap2とmap3を作成します。

f:id:kazuhironagai77:20200802215818p:plain

f:id:kazuhironagai77:20200802215832p:plain

f:id:kazuhironagai77:20200802215842p:plain

区別がつくようにちょっとだけ色を変えました。

後、Reflection captures …と表示されていて結局buildしないといけないみたいですね。この事も後で検討します。

Waypointを作成します。前回作成したのをそのまま使用するのが簡単なのですが、このwaypoint、アクター内で2つ以上のStatic Mesh Componentを使用して形状を作成するという、結構大事なポイントがあるので一応今回も作成する事にします。

f:id:kazuhironagai77:20200802215902p:plain

MeshよりもTextRenderを使用したりConstructionScriptを使用したりするところがあり、そっちの方が勉強になりました。

f:id:kazuhironagai77:20200802215922p:plain

Waypointを配置しました。

f:id:kazuhironagai77:20200802215943p:plain

W_mapを作成しました。

f:id:kazuhironagai77:20200802220023p:plain

ThirdPersonCharacterに以下のコードを追加する事でMを押すとマップが表示されるようにしました。

f:id:kazuhironagai77:20200802220050p:plain

SetInputModeGameAndUIとSetInputModeGameOnlyはここで使用しています。

f:id:kazuhironagai77:20200802220108p:plain

このように使用する事で、

W_mapを閉じた瞬間にマウスのcursorが消えます。

スクリーンショットはマウスのcursorが消えてしまうので取れなかった。)

このやり方は全部のウィジェットに適用すべきで、後で直します。

ここから先はほとんど前回と同じなので省いて結果だけ示します。

f:id:kazuhironagai77:20200802220145p:plain

f:id:kazuhironagai77:20200802220158p:plain

f:id:kazuhironagai77:20200802220208p:plain

f:id:kazuhironagai77:20200802220217p:plain

f:id:kazuhironagai77:20200802220225p:plain

f:id:kazuhironagai77:20200802220235p:plain

ハイ出来ました。

このチュートリアルで真に重要なのはSetInputModeGameAndUIとSetInputModeGameOnlyを使用する事でプレイ画面に切り替えた瞬間からマウスのカーソルを表示させない事です。pause画面を表示した場合もこの機能を使用してマウスのカーソルを消すべきです。

1.2 ブログの内容(11月3を追加する

うーん。一読したら、一体何しているのか良く分からないです。よくよく読んで理解出来たのですが、要するに先週は、Fast Travel Within A single Level and Multiple Levels - (UE4)を真っ新なプロジェクトに作成したので、今度は今までゲームを作成しているプロジェクトであるch2に追加する。と言う事みたいです。と言う事はこの週の内容は既に終わらせていると言う事になりますね。

さらっとだけ復習して終わりにします。

f:id:kazuhironagai77:20200802220320p:plain

とありますが、この時はゲーマーがどんな人達なのは知らないからこんな呑気な事を言っているんでしょうね。ゲーマーなんて隙あらばチートするんだからもうこれは絶対消した方がいいに決まっています。

f:id:kazuhironagai77:20200802220341p:plain

前回のプロジェクトではスタート画面はUE4C++で作成していました。今回はBPから作成しています。

どっちが良いと言うわけではないですが、両方のやり方を覚えておいた方がいいですね。

あれ、でもRPGGameModeBaseクラスでBeginPlay関数を

f:id:kazuhironagai77:20200802220403p:plain

こうやって書いたからBPであるRPGGameModeBaseBPからEventBeginPlayは呼べなかったんじゃなかったのかな。

確認します。

f:id:kazuhironagai77:20200802220424p:plain

レベルBPから呼んでました。うーん。成程。

この週のブログはこれで終わりですね。

1.3 ブログの内容(11月10日)を追加する。

プレイヤーが操作するキャラの3Dモデルの交換を行っていました。これは最初にやった時で、かなりおっかなびっくりやっています。

f:id:kazuhironagai77:20200802220507p:plain

このブログの内容は既に終わっているのでスキップします。

1.4 ブログの内容(11月17日)を追加する

プレイヤーが操作するキャラに武器を持たせられるか試していますが、実際にコードを書いて変更する処まではやっていないみたいですね。

それ以外は既にch4_3でも実装されている内容なのでこのブログもスキップします。

1.5 ブログの内容(11月24日)を追加する。

UIの日本語化を行っています。やります。

全部やりましたが以下に一部示します。

f:id:kazuhironagai77:20200802220548p:plain

f:id:kazuhironagai77:20200802220556p:plain

f:id:kazuhironagai77:20200802220608p:plain

f:id:kazuhironagai77:20200802220617p:plain

f:id:kazuhironagai77:20200802220627p:plain

f:id:kazuhironagai77:20200802220649p:plain

UIのデザインが教科書のそれなので作り直さないと醜いですね。

店主のセリフを大量に追加していますが、これは後で考えるので今回はやりません。

次に店主の3Dモデルを変えます。

f:id:kazuhironagai77:20200802220719p:plain

今度はこんなのにして見ました。

お店も作成します。

f:id:kazuhironagai77:20200802220741p:plain

最初なんで、こんなもんです。

この後、武器を追加していますが既にやっているのでこの週のブログの内容は全て追加出来ました。

1.6 ブログの内容(12月1日)を追加する。

この週のブログではモンスターを追加しています。

モンスターは既に追加しているのですが、そのモンスターにAIはまだ搭載していませんのでその辺を作って行きます。

ぱっと読んだんですがやり方を忘れてしまっていてどうすればいいのか分かりません。

取りあえず、AutoPossessAIをPlacedinWorldorSpawnedに変更しました。

f:id:kazuhironagai77:20200802220812p:plain

空中に浮いていたモンスターが地面に足を付けています。

f:id:kazuhironagai77:20200802220838p:plain

正確に言うと今でも僅かに浮いていますが、前と比べてると地面に足を付けていると言って良いです。(以下に前の状態を示します。)

f:id:kazuhironagai77:20200802220903p:plain

これでこの週のブログは終です。

1.7 ブログの内容(12月8日)を追加する。

こっちのブログにモンスターのAIの作成方法が詳しく説明されていました。これに沿ってAIも実装してみます。

出来ました。モンスターが追いかけて来ます。

f:id:kazuhironagai77:20200802220940p:plain

出来たんですが、何をやっているのか全く忘れてしまいました。後でAIの復習をする事にします。

1.8 ブログの内容(12月15日)を追加する。

この週のブログはAIの勉強だけしていますね。後でやります。

1.9 ブログの内容(12月22日)を追加する。

この週もAIの勉強だけしています。どうもUE4のAIがIF-statementだけで構成されているのでそれがAIなのか心配になって色々なAIの本を読んでいたみたいです。普通AIと言えば機械学習とか深層学習とかを指していると思われるからその辺を突っ込まれても大丈夫にしたかったみたいです。

今考えればそんな事はどうでも良くて、UE4で敵のモンスターが私が希望したように動いてくれる事のみが大事です。

1.10 ブログの内容(12月29日)を追加する。

これから直すリストを作成しています。後、無料のinventory systemを試していますね。そんだけです。

1.11 ブログの内容(1月12日)を追加する。

色々書いていますが、やったのは道具を使用した時にアイテムが消費されないバグを直す事だけです。これはch4_3でも既に直しています。

1.12 ブログの内容(1月19日)を追加する。

この週のブログではそれぞれのアイテムにイメージを追加してそれを買い物中に表示するようにしていますね。この機能をch4_3に追加します。

ブログに詳しい説明が書かれているのでそのまま作成します。

f:id:kazuhironagai77:20200802221035p:plain

出来ました。

ブログではマウスが外れた時に、このウィジェットを消す機能は作成していないですがその部分も作成しました。

この週のブログは他にも色々やっていて一個ずつ潰していきましょう。

1.12.1 道具の効果にHP以外も追加

これは既に作成したと思いますが確認します。

f:id:kazuhironagai77:20200802221112p:plain

イーサーを使用したらMPが0から20になりました。出来ています。

1.12.2 ワープしても所有している道具が消えないようにする。

しました。

これは単にThirdPersonCharacterで作成したアイテムを保持する配列の代わりに元々、アイテムを保持するためにRPGGameInstanceの変数Itemsにアイテム名を保持させるだけで出来るはずです。

f:id:kazuhironagai77:20200802221142p:plain

アイテムを使用したので配列から名前を消去する場合、ThirdPersonCharacterのText配列と違って以下に示したように非常に簡単に出来ました。

f:id:kazuhironagai77:20200802221202p:plain

テストします。

f:id:kazuhironagai77:20200802221220p:plain

アイテムを所持した状態でワープします。

ワープした後でpauseを開くと

f:id:kazuhironagai77:20200802221240p:plain

所持しているアイテムはそのまま持っています。はい出来ました。

1.12 ブログの内容(2月2日)を追加する。

武器屋を作成します。

この週のブログに詳しい作成方法が載っていますので同じようにやります。

うーん。完成した結果だけ載せようと思っていたのですが、この週のブログ結構説明が抜けています。説明が足りない部分の補足をここに示しておきます。

f:id:kazuhironagai77:20200802221305p:plain

ここで説明されている新しいNPCDialogですが、WeaponShop_Welcomeウィジェット内に作成するのではなくWeaponShop_Welcomeウィジェットの親クラスであるNPC_Parentクラス内に作成します。

テキスト内の文字がはみ出してしまうが直し方が分からないと言っています。

Textboxを選択して以下の箇所にチェックを入れれば文字はテキストボックス内に表示されます。

f:id:kazuhironagai77:20200802221325p:plain

f:id:kazuhironagai77:20200802221333p:plain

次に武器屋で買い物が出来る様にします。

あんまりコードを変えたので結果だけ示します。

f:id:kazuhironagai77:20200802221356p:plain

武器屋で短剣を買いました。それを装備します。

f:id:kazuhironagai77:20200802221416p:plain

短剣(小)を装備した時は攻撃値が10上がりました。

f:id:kazuhironagai77:20200802221439p:plain

短剣(大)を装備した時は攻撃値が15上がりました。

これでこの週のブログの内容は一応終わりました。

2.まとめと感想

今週はここまでとします。流石に一回やった物かつブログに詳細な手順が書かれていると簡単に再現出来ます。ひょっとすると来週には終わるかもしれません。