UE4の勉強記録

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

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する Bug直しの続きとSaveの改善

f:id:kazuhironagai77:20210117212957p:plain

<前文>

長母音と短母音について

英語の発音記号についてなんですが、ネットとかで英語の発音を教えているほとんどのアメリカ人は大学で言語学の学位を取った人じゃないんです。だから話半分に聞いておくべきなんです。そう言う考え方もあるよね。ぐらいで。

その例として、今回ここで述べておきたいのは、long i とshort iの音の長さは同じと言う説です。

あるサイトでleaf とliveのそれぞれのlong i とshort i の音の長さを測定したんですが全く同じ長さだった。とありました。実際はこのサイトだけでなく結構な数の英語の発音を指導するアメリカ人がlong i とshort i の音の長さは同じと主張しています。

ただそのサイトで提供されていたleaf とliveの音を聞くとliveのiの音の方が短く聞こえたので、本当に二つの単語のiの音の長さが同じなのか自分で測定してみました。

f:id:kazuhironagai77:20210117213034p:plain

そしたら、0.235秒でLiveはVの音が聞こえるますが、LeafのFの音はまだ聞こえないんです。

つまり、私が測定した限りではshort iの音はlong iの音より短かったんです。

本当にこのサイトの主は自分で音を測定したんですかね?

査読付きの論文にうそのデータを載せたら大変です。しかしその辺にたむろしているオッチャンが、運動部の練習している高校生に「水取らないと、危ないぞ。」と言っても、それって「水分を取るべきって言うべきで、生理的食塩水なら運動中に摂取すべきですが、単なる水道水を運動中に摂取したら…」と言い返す人はあんまりいないです。

英語の発音についても同じ事が言えます。ネットで英語の発音を指導するアメリカ人のほとんどは大学で専門に勉強した人ではなく単なるその辺のオッチャンと同じレベルの人です。その人が述べる指導方法で上達する事が出来ないのは自明ですが、それをわざわざ指摘する人は野暮なだけです。

所がですが、一端ネットに載ってしますと、その人が凄腕のコーチなのか、その辺のオッチャンなのか、区別が付きにくくなってしまうんです。その辺のオッチャンがどこかの有名大学の教授の様に見えたり、その逆もあったりします。

だからネットで言われている意見については自分でチェックするのは非常に大切と思います。

アメリカ議会の占拠と殺人

今回の大統領選挙で、不正が行われていると信じてアメリカ議会の占拠をした人達はとうとう殺人まで犯してしまいました。個人的には、この事件の本当の犯人は、偏った意見を述べるinfluencerを一人でも見ると、同じような意見を持つ人ばかり表示するネットのAIだと思います。反対意見が全く表示されない状態で、同じような意見を色々な有名人が述べたら、一般の人は直ぐに信じてしまいます。

しかしほとんどのアメリカ人は単純に、右が間違いで左が正しい、そして問題は解決したと安心しています。

今回の事件で、右寄りの意見を言っていた人は暫く肩身の狭い思いをすると思いますし、実際反省すべきですが、アメリカのリベラルが同じ間違いをこれから犯さないとは私には思えません。今回の問題を引き起こした原因であるネットのAIについて誰も言及しないからです。

私は近い将来、今度は以下の分野でリベラルが同じような問題を起こす可能性があると思っています。

  • 私は、地球温暖化はかなり怪しいと思っています。これから地球は寒くなると思っています。これは単なる個人的な見解ですが、地球温暖化ビジネスに未来のトランプが潜んでいたら。今回以上の事件を将来、リベラルが起こす可能性は非常に高いと思われます。
  • 福祉の充実こそが左派に求めらてれている政策です。しかし実際にそれを実行するリベラルは民主党で浮いた存在になるでしょう。適当な政策でお茶を濁すはずです。個人的な注目は大学の学費です。これが下がるかどうかで民主党の福祉に対する本気度が分かると思います。
  • 無意味なポリコレの強制。これは日本人には馴染みの問題過ぎて、私がここで解説する必要はないですが、一応述べておきます。絵を無くしても問題の解決にはつながりません。

これから犯罪をそそのかす、このようなデマに騙されないためには、前述した発音の問題の様に、一々チェックするのが最適ですが、実際は忙しすぎるのと専門分野以外の話は正しく理解する事すら出来ないので不可能です。

これに対する秘策を実は思いついちゃったんです。

名付けてHxH式操作系念能力者識別法です。

これについて解説すると長くなりすぎて勉強時間が取れなくなってしまうのでこの話は来週に回します。

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

<本文>

1. 今週の予定

先週、量が多すぎるので中止した2つのバグを直します。

  • 徘徊するモンスター用に別なAIを作成
  • PlayAnimationノードの使用は中止。アニメーションはAnimBPで一括して管理する

更に、今まで適当にしていたsave機能を完成させたいと思います。

1.1 (!!)の表示について

先週、作成した後でInstance editableなBoolean 変数を一個作成すれば、わざわざRPGGameModebaseBPに新しい変数を作成する必要もないと思ったのですが、面倒だったので試さなかったです。

試してみます。

f:id:kazuhironagai77:20210117213150p:plain

f:id:kazuhironagai77:20210117213159p:plain

f:id:kazuhironagai77:20210117213207p:plain

f:id:kazuhironagai77:20210117213216p:plain

これで、RPGGameModebaseBPに作成した新しい変数を使用しないで、(!!)の表示が出来るはずです。

テストします。

f:id:kazuhironagai77:20210117213234p:plain

出来ました。

RPGGameModebaseBPのItemNameToPickup変数はいらないので消します。

因みに、拾ったitemを消去する関数内でもRPGGameModebaseBPのItemNameToPickup変数は使用していましたが、以下のように実装を変更する事で、RPGGameModebaseBPのItemNameToPickup変数を使用しないでも収得したアイテムが2度以上表示される事は無くなりました。

f:id:kazuhironagai77:20210117213255p:plain

一応テストした結果も記録として残しておきます。

f:id:kazuhironagai77:20210117213329p:plain

2. 徘徊するモンスター用に別なAIを作成

徘徊するモンスター用のAIを作成します。

2.1 AIの復習

もう一通りの基本は理解しているので細かい点の復習を兼ねてこのサイトUE4_AIの勉強をします。前に途中までこのサイトでUE4_AIの勉強をしたので選びました。

Part 2 AI Perceptionまで見て思ったんですが、これそのまま作成したら十分です。

今のAIはプレイヤーが操作するキャラがNavの領地に入ると、モンスターはどうやってプレイヤーの操作するキャラを見つけたのか分からないけど猛烈に追いかけて来ます。それでモンスターに視覚のようなモノを与えたかったのですが、このチュートリアルはそのものズバリです。そのまま作成して使用する事にします。

前回、勉強した時UE4のAIの全体像が知りたかったので、正直駄目なtutorialとは思いました。2020-12-06のブログで述べましたが「UE4_AIそのものは単なるif節である。」との認識こそが、当時の私が知りたかった事でした。その次のステップとして「AIがコントロールするキャラの動きをもっと自然にしたい。」となった時にこのtutorialは非常に役に立ちます。

前回の勉強をまとめたブログを参考にしつつ、もう一回このtutorialを勉強します。

2.1.1 The Behaviour Tree

この回のTutorialは、AIController、BehaviorTree、BlackboardなどのUE4_AIを構成するクラスの使用方法を説明しています。Behavior TreeについてはTaskの作成についてかなり細かく説明してます。

ただし、私がUE4_AIの基本を説明するために最も大切であると考える「UE4_AIそのものは単なるif節である。」の認識を得る事はこのTutorialからは不可能です。そういう意味では初心者にとってはあまり良くないです。

前回勉強した時のブログを読むと「この回のtutorialに載っている事は全部知っている事である。」とまとめられていました。

今、読み直すと「全部知っている」は完全な嘘で、例えばTaskクラスのEvent関数である以下に示したものの違いは今でも分かっていません。

f:id:kazuhironagai77:20210117213423p:plain

やっぱり人間は本当は良く分かっていない時には「全部分かった」の様な過剰な自信をみせる発言をしてしまうんですね。

一寸だけ、これらのEvent関数の違いを調べて見ましょう。

このサイトにAIとGenericの違いの説明がありました。

f:id:kazuhironagai77:20210117213442p:plain

この説明によるとAIControllerを使用した場合は、AIのEventを選択する必要があると書かれています。

Abort、ExecuteとTick関数の違いについては、見つかりません。

このサイト

f:id:kazuhironagai77:20210117213502p:plain

簡単なBehavior Treeを作成してテストしたら理解出来るとありましたので、試してみます。

以下の様なBehavior Treeを作成しました。

f:id:kazuhironagai77:20210117213520p:plain

Task、PrintStringを以下の様に作成しました。

f:id:kazuhironagai77:20210117213538p:plain

これでテストします。

f:id:kazuhironagai77:20210117213557p:plain

普通にPrintされました。

次にAbort AIを接続します。

f:id:kazuhironagai77:20210117213615p:plain

これでテストします。

f:id:kazuhironagai77:20210117213637p:plain

あれ、何も表示されません。

この方法じゃ単純過ぎてAbortは発動しないのかと思って停止したら、その瞬間に表示されました。

f:id:kazuhironagai77:20210117213655p:plain

AIをAbortした時とは、そのAIが開放された時、つまり一般的に言えばゲームを終了した時に発動するTaskのようです。

そうするとTickはそのAIを使用している間、ずっと発動していると言う事になります。

Tickも確認してみましょう。

f:id:kazuhironagai77:20210117213713p:plain

テストします。

f:id:kazuhironagai77:20210117213730p:plain

その通りでした。

一般的なTaskを作成する分にはExecute AIだけ使用すれば良いみたいです。

2.1.2 AI Perception

前のブログを読んでみたらAIPerceptionについて結構勉強していました。はっきり言って何も覚えていません。動画を見るとAIPerceptionを使用してAIが操作するキャラに視覚を追加しています。ここで知りたい事は、どうやってAIが操作するキャラに視覚を追加出来るのかです。

それをまず勉強します。その後で、前のブログに書かれているAIPerceptionについての勉強を読んでみます。

AI Perceptionを使用する前に、Behavior Treeを以下に示した様に変化させました。

f:id:kazuhironagai77:20210117213809p:plain

Blackboardに作成したBoolean変数であるCanSeePlayerがfalseなら左側、trueならば右側のSequenceが実行されるだけです。

f:id:kazuhironagai77:20210117213826p:plain

このCanSeePlayer変数の値をAIPerceptionを使用して変えます。

まずAIPerceptionですがAIControllerクラス内に作成します。

f:id:kazuhironagai77:20210117213845p:plain

f:id:kazuhironagai77:20210117213852p:plain

作成したら、AIPerceptionのSenses Configにelementを一つ追加します。

そしてImplementationの項目をAlSense_Sightにします。

これは視覚を使用すると言う意味だそうです。

f:id:kazuhironagai77:20210117213910p:plain

以下の項目にチェックを入れましたが、単に敵も味方の第三者も同列に扱うと言う意味です。
詳しい説明は後のtutorialに出てくるそうです。

f:id:kazuhironagai77:20210117213928p:plain

今度は見られる方のキャラクター、この場合はThirdPersonCharacterにAIPerceptionStimuliSourceを追加します。

これが在る事でAIPerceptionから知覚される事が可能になります。今回の場合は視覚によって見つかると言う事になります。

f:id:kazuhironagai77:20210117213957p:plain

更に、AIPerceptionStimuliSourceのAI Perception内でAuto Register as SourceをチェックしてRegister as Source for SensesにAlSence_Sightを選択します。

こうする事で、敵から視覚によって認識されるようになります。

f:id:kazuhironagai77:20210117214024p:plain

そして、AIController内で以下ように実装します。

f:id:kazuhironagai77:20210117214039p:plain

On Target Perception Updated(AIPerception)を使用する事や使用方法については特に疑問はないんですが、これだと一端BlackboardのCanSeePlayer変数がtrueになったらその後はずっとtrueのような気がします。調べてみたらそんな事は無かったですが少し不思議です。

まあ、それ以外でそんなに難しい事はありませんね。

  • 見る側にAIPerception
  • 見られる側にAIPerceptionStimuliSourceを追加する事
  • Eventの開始はAIController 内にOn Target Perception Updated(AIPerception)を使用する事

と言う事ですね。

今度は前に勉強した内容を読んでみます。

一杯書かれていて、沢山勉強していますが、先程説明した

  • 見る側にAIPerception
  • 見られる側にAIPerceptionStimuliSourceを追加する事

が分かっていないみたいです。それで大変混乱しています。

去年、理解出来ていなかった内容が今は理解出来ると言う事は、UE4の勉強が着実に進んでいる証拠でもあります。だからまあ良いでしょう。

2.1.3 Chasing the Player

一端、追いかけ始めたら普通ならずっと追いかけるはずです。しかし今のAIはキャラを見失ったら適当な場所に行ってしまいます。それを直します。

Behavior Treeのdecorator、blackboardの設定であるFlow ControlのObserver abortsの値をBothに変更します。

f:id:kazuhironagai77:20210117214225p:plain

しますがこの意味が良く分かりません。一応説明しているのですが、よく聞き取れません。

このサイトに説明されていました。

f:id:kazuhironagai77:20210117214251p:plain

分かりました。

これは何かを実行している途中で、If節の条件が変わってしまった時の対応について決めているです。

  • 普通のif節だったら、条件をチェックした後にその条件が変わっても無視してそのまま進行します。これと同じなのがNoneです。
  • Selfに設定した場合は、今いるNodeとその下にあるNodeの実行を止めて、隣のnodeを実行します。
  • Lower Priorityは今いるnodeとその下に付いているnodeは実行しますが、今いるnodeより右側にあるnodeは無視します。
  • 最後のBothは全部中止して一つ上のnodeに戻ります。

これで合っているはずです。Bothにセットしていますので、Playerを見かけたら何かをやっている途中でもPlayerを追いかけてくるはずです。

テストします。

正直、良く分かりません。色々条件を変更しましたが、完全に上記の解釈が合っていると確認は出来ませんでした。

Playerが逃げ続ける場合、AIはPlayerに対して真っ直ぐ追いかけるはずですが、実際はジグザグに追いかけています。これを直します。

直し方は単純で、新しいTaskを作成してそれをMove toの代わりに使用します。

f:id:kazuhironagai77:20210117214324p:plain

ジグザグは直りましたが今度はカクカクするようになってしまいました。

解決策はCool down Decoratorを追加する事です。Cool down Decorator はDelay関数と同じ働きをするみたいです。

f:id:kazuhironagai77:20210117214342p:plain

0.2秒にセットしたらカクツキが無くなりました。

最後にカーブを曲がるときにもっとスムーズに曲がれるようにします。

以下の部分の設定を変更しました。

f:id:kazuhironagai77:20210117214358p:plain

この項目はPlayer controllerによってキャラクターが操作されている場合にcheckすべきなんだそうです。だからcheckを外します。

f:id:kazuhironagai77:20210117214416p:plain

こっちの設定は回転する時にスムーズに回転するための設定らしいです。正直良く分かりません。

テストしてもこの部分は実際の違いは正直分かりませんでした。

以上です。

最後に前、勉強した時は何と言っていたのか確認します。

まず、Behavior Treeのdecorator、blackboardの設定であるFlow Controlの設定についてですが、以下の様に述べています。

f:id:kazuhironagai77:20210117214439p:plain

これって一個ずれていますね。と言うか、今回勉強した時は、この説明の部分何言っているのか聞き取れなかったんですが、前回勉強した時は普通に聞き取れていたみたいですね。イギリス訛りなんで結構聞きにくい部分があるんですが、日本に帰って来てからlistening力落ちていますね。結構ショックです。

もう一回、今度は真剣に聞いてみます。

言っていますね。Noneの時に一連の動作を止めて、次のNodeの動作をすると。これはこのサイトの説明と違いますね。このサイトではNodeはなにもしないと言っています。多分サイトの説明の方が合っているんでしょう。Tutorialの説明はLower Priorityの辺りからモゴモゴ言って何を言っているのか分からなくなっていますから。

簡単なテスト方法を思いついたら後で確かめてみます。と思ったら、前回も同じ事言っていました。

その後の解説は今回と全く同じです。最後のAIが回転する所が良くなっていると言っているが全然分からないと今回と全く同じ事言っています。

そして最期にこんなのAIの勉強じゃないと怒っています。

まあ。UE4のAIの基本を知りたい時に、こんな走り方の微調整のやり方を教わっていたら、頭に来るのは分かります。ただ今回は実際のモンスターのためにもっとマシなAIを作成したいと言う目的があるので、モンスターが回転する時の微調整なんかも大切です。のでもうちょっとだけ勉強を続けようと思います。

2.1.4 Patrolling NPC

今度はNPCにパトロールをさせるそうです。正直この機能こそモンスターのAIに追加したかった機能です。しっかり勉強しましょう。

まずactorクラスからBPを作成します。PatrolPathと名付けます。

f:id:kazuhironagai77:20210117214502p:plain

このクラス内にVectorタイプのarray変数であるPathPointを作成します。

この変数はInstance editableです。

f:id:kazuhironagai77:20210117214519p:plain

このクラスのinstanceをマップ内に配置します。

f:id:kazuhironagai77:20210117214536p:plain

配置したinstanceのPathPointに3つの要素を追加します。

f:id:kazuhironagai77:20210117214552p:plain

f:id:kazuhironagai77:20210117214600p:plain

注意点として最初の要素の値は0,0,0である必要があるそうです。

このInstanceで指定した場所にNPCは移動していきます。つまりNPCにパトロールをさせると言う事は、このPatrolPathのinstanceが保持するPathPointの値をどうやってUE4_AIに渡すのかと言う事につきます。

次にNPCのBPを開きPatrolPathタイプの変数、PatrolPathを作成します。

f:id:kazuhironagai77:20210117214639p:plain

この変数はInstance Editableに指定します。

配置したNPCのinstanceのPatrol Pathに先程作成したPatrolPathのInstanceを指定します。

f:id:kazuhironagai77:20210117214704p:plain

これは名前がクラスとinstanceが同じなので混乱しますが、全部Instanceです。

なので、それぞれのNPCに違う場所のパトロールをさせる事が出来るはずです。

次にBehaviorTreeを示します。

f:id:kazuhironagai77:20210117214729p:plain

Blackboardには2つの変数を追加しました。

VectorタイプであるPatrolPathVectorとintタイプであるPatrolPathIndexです。

f:id:kazuhironagai77:20210117214745p:plain

最初のTaskであるFindPathPointで移動する場所のVectorNPCからBlackboardに新しく作成した変数、PatrolPathVectorにパスします。

次のTaskであるMove toでその場所に移動します。

その次のTaskであるIncrementPathNextでPatrolPathIndexの値を1だけ増やします。

FindPathPointの実装です。

f:id:kazuhironagai77:20210117214802p:plain

NPCをどうやってパスするんだと思っていましたが、EventReceiveExecuteAIから直接得る事が出来ました。

そこさえ分かれば後は普通のUE4_AIの作成と同じです。

前回の勉強の記録もチェックしておきます。

3Dwidgetについての解説が書かれていました。

f:id:kazuhironagai77:20210117214820p:plain

これは重要な事でした。

後は、ソフトウェアデザインの観点からComponentとしてPatrolPathタイプの変数を作成しているのが注目と述べていました。これは言われてみればそうです。あの当時はゲームにおける正しいソフトウェアデザインとは何か?について凄い考えていたのでこんな事も考えていたんですね。

2.1.5 Patrolling NPC Continued

NPCがずっとパトロールする様にセットします。

取りあえず、前回の勉強ではどんな事を言っていたのか確認したら

f:id:kazuhironagai77:20210117214842p:plain

とありました。

思い出してきました。この辺はもうやりたくなくて兎に角辞める理由を探していた所に、tutorialで言っている通りに動かないのでこれ幸いとここで中止にしたのでした。

ただ、本当に Tutorial通りにやっても駄目だった場合はどこが駄目だったのか記録する必要はあったと思います。その辺も含めてもう一度やってみます。

f:id:kazuhironagai77:20210117214859p:plain

普通に出来ました。

最後までやったのですが普通に動きました。 Tutorial通りにやっても何処にも問題ありませんでした。

うーん。

これはどう総括すべきなんでしょうか?

. まとめと感想

今週は、UE4のAIの復習をやっているだけで終わってしまいました。しかしUE4のAIも一通り勉強する必要があるので、来週もこのままtutorialの続きをやる事にします。

UE4_AIはどの辺まで理解すれば基本は出来たと言えるのでしょうか?

TaskクラスのEvent Abort AIやDecoratorのObserver abortsの値であるSelf やLower Priorityも理解する必要があるのでしょうか?

この辺の疑問を解消するため、久しぶりに「Unreal Engine 4で極めるゲーム開発」を読んでみました。23章に少しだけですがかなり深堀した解説がありました。その説明は私の理解している機能とちょっと違っていたので「え!そんな意味だったの?」とかなり驚きました。TaskクラスのEvent Abort AIやDecoratorのObserver abortsの機能に関しては、来週も引き続き勉強します。