<前文>
前文には、日本人が誤解しているアメリカ、特に日本文化とキリスト教文化の違いから生じる誤解とその解決法について気が付く範囲ですが書いていきます。
これからのInternet社会において、多くの日本人は、望む、望まずに限らず生のアメリカ人との関係が最も重要になって来ます。
そして、私のこの前文には、どうやってアメリカ人と良好な関係を築けるのかのヒントが隠されていて、私が指摘している点を気を付けるだけでも、最悪の事態を避ける事は可能です。
ところで最近気が付いたんですが、日本のネットの意見って一般の日本人の意見と大分違うと言う事です。例えばネット上だとBLM運動の参加者に対して日本人全体が激しく差別的な発言を繰り返しているように見えましたが、実際の日本人の大多数はBLM運動の参加者に対して大変好意的だった事です。
ほとんどの日本人はネットの意見なんて信じていなかったんですね。
安心しました。
一応念のために言っておきますが、日本のネットの意見をそのままアメリカ人に伝えるとアメリカ人は見た事無い位、激怒しますよ。
激怒するだけじゃなくて場合によっては社会的、もしくは法的な罰を与えられます。会社の上司だったり、学校の先生だったりした場合、解雇されたり退学にさせられたりします。その激怒したアメリカ人が政府関係者だったらアメリカに入国禁止にされるかもしれません。その位の内容が日本のネットには書かれています。
この辺の話題こそ、私が前文に書いていくべき内容だったのかもしれません。
ネットの意見の中でも、誰が主張しているのか不明な意見には特に注意して下さい。あなたの意見になってしまうからです。政治家の○○さんの意見によれば、と言っておけばある程度は怒りの矛先をかわす事が出来るかもしれません。しかしあなたの意見であるとなったら解雇されたり、退学にされても文句も言えなくなります。
この前もニュースでやっていましたが、ネットで人種差別的な発言をしていたアメリカ人の高校生のHarvard大学の入学が取り消しになりました。アメリカでは発言の自由が保障されている代わりに発言の責任は自分で取る必要があります。彼は未成年であるにも関わらず、発言の責任を取らされた訳です。
ではどうすれば良いのかと言うと普段から英語のニュースを聞いておく事です。
そうする事でアメリカ人と会話する時の安全な話題と超えてはいけないLineが自然と身に付きます。
それでは今週の勉強を始めます。
<本文>
1.今週の予定
今週も先週の続きをやっていきます。
先週は最後の部分は時間が足りずにほとんど出来ませんでした。後、最近は勉強する方が主になってGameの作成の方はかなり少なくなってしまっています。
- Niagara : 先週の続き
- Material : Ben Cloward氏のTutorialを勉強する
- NPCのAIを作成するためのAIの復習の続き
- World CompositionによるMap1の作成
- UE5におけるWorld Partitionの勉強
- Loading Screenの勉強の続き(Moduleについて)
この中で今のRPGの製作に全く関係のない純粋な勉強は、NiagaraとWorld Partitionです。今のGameは4.24で制作しているのでNiagaraは標準では使用出来ませんし、する気もありません。World Partitionに関してはUE5の機能なのでハナから使用するのは無理です。
でもNiagaraの勉強だけは止める気はありません。
何といっても3D Graphicsと直結している分野なのである程度理解したら私の3D Graphicsの専門知識がそのまま活用できる可能性が高いからです。
Materialの勉強も同じです。更にBen Cloward氏のTutorialで勉強する事でぐぐっとMaterialに対する理解が深まっています。これも止めるのは論外です。
World Partitionの勉強はあくまでもWorld Compositionをどの位勉強すべきかの査定をするためにやっている事なので今週で終りに出来ます。
World CompositionとNPCのAIの勉強はGameの作成に直結してるので中止する事は勿論出来ません。
となるとLoading Screenの勉強が一番弱いですね。Moduleの作成方法などの勉強は面白いですが、あまり適切なTutorialが存在しない事。Loading Screenそのものの作成は終わっている事の点から考えて中止すべきはこれでしょうね。
2.Niagara : 先週の続き
2.1 Disintegration in UE5 Niagara Tutorial | Download Files [1] の続き
先週途中まで勉強したCGHOW氏のDisintegration in UE5 Niagara Tutorial | Download Files [1] の続きをやっていきます。
ParticleがEdgeの部分からのみ発生するようにします。
M_ParticleBodyの実装を以下に示した様に変更します。
以下の様になりました。
この方法だと発生したParticleが発生した位置から移動しないそうです。
その解決策として以下の事をしました。
まず、Niagara SystemのScratch Module内にあるDynamic Material Parameterを消します。
すると以下の様にParticleの発生が変わります。
更にParticleの発生用のMaterialの実装を以下のようにします。
当然ですが全身からParticleが発生するようになりました。
Curl Noiseを切るとこんな感じです。
そしてParticle Update SectionでKill Particles In Volumeを使用します。
すると以下の様になります。
更にもう一個同じModuleを以下の条件で追加すると
両方の条件を満たした箇所だけParticleが発生する事になります。
こんな感じになりました。
おお、ParticleをEdgeだけから発生する事が出来ました。
しかしこの方法にも問題がありました。Curl Noiseを追加してもParticleが球のEdgeの範囲内でしか移動しません。
その理由はKill Particle in Volume Module内でParticle Positionを使用しているからだそうです。
うーん。何で?正直分からないと思ったら、次のノードを見たら分かりました。
もしParticleのPositionが球の範囲から出た場合は消してしまうんです。成程分かりました。
これにそっくりなScratch Moduleを作成してこのPositionをInitial Position に変更します。
コピーしている間に新しいTechniqueを一個学びました。
以下に示した様に沢山のノードに繋がったPinはCtrl+マウスの左クリックで一辺に移動出来ます。
これをKill Particle in Volume Moduleの代わりに使用します。
同じ結果が得られました。
Particle Positionの部分をInput InPositionに変更しました。
あれ?ここにInitial Positionを追加するんじゃなかったんでしょうか?
その後でInitial Positionを追加しました。
うーん。いきなり入れたら駄目なんでしょうか?
この辺も後で検討します。
結果はこんな感じです。
ここから最後の仕上げに入ります。
球のActorを用意してその球の動きに合わせてイスが消えてParticleが現れるようにします。
一回軽くTutorialを見たのですが、何でそうやるのか正直、意味不明な部分が有りました。
今は、Tutorial通りに再現出来る事に勤めて、後で何故そうやったら出来るのかは検討します。
Kill Particle in Volume Moduleの代わりに新しく作成したModuleのOrigin OffsetにRead from new User parameterを選択します。
初めてName SpaceがUserのParameterを作成しました。後Make Read from User Parameterも始めて使用します。
この辺についても後で調べます。
System SettingsのUser Parameter Moduleを選択すると
Origin Offsetの変数が出来ていました。
はあ。これがUserなんですね。
こっちにもOrigin Offsetが出来ていました。
そう言う事ですか。成程。
今度はこのLevelのBPを開きます。
何気にUE5のBPを使用するのは初めてです。
以下の様な実装をしました。
更にLevel上に球を追加してその球の位置をSet Niagara Variable (vector3)のIn Valueに追加します。
以下に示した様に追加しました。
Playにして試したらParticleの発生の仕方がTutorialとちょっと違います。
そうです。境界上に現れていません。
色々調べましたら良く分かりません。球の境界が良く分からないのでひょっとすると合っているのかもしれません。
後で又検討します。
先週作成したMaterial Parameter Collection であるMPCにVector Parameterを追加します。Parameter NameはLocationです。
イスのMaterialに先程作成したMaterial Parameter Collection であるMPC 内のLocationを今まで使用していたLocationと交換します。
そしてLevelのBPで以下の実装を追加します。
やっぱりParticleの何かがずれていますね。
調べたらParticle Update SectionのKill Particle in Volume Moduleの代わりに新しく作成したScratch ModuleのInPositionが外れていました。
これで試します。
出来ていますね。
2.2 Disintegration in UE5 Niagara Tutorial | Download Files [1] で使用したModuleなどの調査
Disintegration in UE5 Niagara Tutorial | Download Files [1] で初めて使用したModuleなどの機能を調べます。
<Sample Static Mesh Module>
この二つのModuleは椅子の形にParticleを発生させるのに使用しましたが結局は、Scratch Moduleで一から作成したModuleと交換しました。
今回は試しに別なMeshを使用してみました。
解説を探したのですが公式のDocumentであるParticle Spawn Group [2] にちょっとだけ解説があっただけした。
うーん。これだけじゃ何とも言えないです。
Static Mesh Location Moduleの変数であるSample Mesh NormalとSample Mesh Position にSample Static Mesh Moduleの変数であるMesh NormalとMesh Positionが使用されています。
これが上記の言っているThose Sampled Valuesの事を指しているんでしょうか?
この二つの変数の値は、Sample Static Mesh ModuleのScriptを開いて見ると
何回も見たRandomに選んだMeshのPositionやNormalを示すノードです。
これさえパスすればStatic Mesh Location ModuleはMeshの形にParticleを生成するんでしょうか?
Scratch Pad Moduleで試してみます。
以下の実装を作成しました。
このoutputしている変数、myPositionとmyNormalをStatic Mesh Location Moduleの変数であるSample Mesh NormalとSampled Mesh Positionにセットします。
警告は表示されたままですが、以下に示した様にParticleを指定したMeshの形に生成する事が出来ました。
大体何をやっているのか分かりましたね。
2021-09-06のBlogで以下の事を述べています。
これは、Particle Spawn Group [2]をみると実際は以下の様になっています。
それぞれのModuleのScriptを見てどう違っているのかを確認してみます。
<<Initialize Mesh Reproduction Sprite Module>>
Skeletal MeshのRandom Coordinateの値を変数であるMesh Tri Coordinateにセットしています。
その値を元にしてSkeletal MeshのPositionを求めそれをOUTPUTかつModuleであるPositionにセットしています。
OUTPUTもMODULEもどんなName Spaceなのかちょっと分からないですね。
最後にParticleであるPositionに値をセットしています。
Initialize Mesh Reproduction Sprite ModuleではいきなりPositionに値をセットしてしまうんですね。
Normalの方はSprite Facingにその値をセットされていました。
<<Sample Skeletal Mesh Skeleton>>
このModuleはUE5のNiagaraでは見つからなかったです。
<<Sample Skeletal Mesh Surface>>
これも無かったです。
<<Sample Static Mesh>>
これはさっきやった奴です。
<<Update Mesh Reproduction Sprite Module>>
これは、Building advanced effects in Niagara | Unreal Engine [3]で使用したModuleでInitialize Mesh Reproduction Sprite ModuleとPairで使用します。
2021-09-12のBlogでちょっとだけ勉強しました。
<<ParticleをMeshに沿って発生させるModuleのまとめ>>
この結果だけみるとSkeletal Meshの場合は、Initialize Mesh Reproduction Sprite Moduleを使用し、Static Meshの場合はSample Static Meshを使用すると考えて良さそうです。
更に、Initialize Mesh Reproduction Sprite ModuleはUpdate Mesh Reproduction Sprite ModuleとPairで使用しSample Static Mesh ModuleはStatic Mesh Location ModuleとPairで使用します。
因みにContent ExamplesのこのSampleは
Initialize Mesh Reproduction Sprite Moduleを使用していました。
<Static Mesh Location>
もう大体、このModuleが何をやっているのか分かりますね。Sample Static Mesh ModuleでOutputされたPositionの値をParticle Positionにセットしている訳です。
Scriptを見るとNormalの方はOffsetを計算する時に使用しているようです。
これだけ分かれば十分です。
<Materialについて>
Disintegration in UE5 Niagara Tutorial | Download Files [1]ではStatic Mesh用のMaterialとParticle用のMaterialの2種類が使用されています。
<<Static Mesh用のMaterial>>
ここで大切な事はどうやってMeshの一部をMaterialを使用して消しているのかと言う事でMaterial全体の内容はあんまり重要ではありません。
そのMeshを消すためのPinがOpacity Maskです。
このPinへの接続方法を理解しながら今回の実装について観察していきます。
これだけです。
他のノードもありますが結局はSphere Maskノードが全部やっています。
Building advanced effects in Niagara | Unreal Engine [3]ではDitherTemoralAAノードを使用していました。
こういうある意味特殊なノードがOpacity Mask専用であるのかもしれませんね。
このMaterialの勉強はこれで終わりでも良いんですが、先週
と書き残していたので、3Color Blendノードについて調べます。
公式のDocumentであるImage Adjustment [4]に以下の説明がありました。
いやいや、2つをGray Scaleで表すなら意味が分かりますが、3つの色をどうやってGray Scaleから割り振るの?
そしたら
こうやって割り振るそうです。
試してみます。
こんな結果になりました。
説明の通りですね。でも緑の幅が大き過ぎる気がします。この割合は変化出来ないんでしょうか?
まあいいです。これだけ分かれば十分です。
ここからは今週やった内容の調査になります。本当は一週間熟成させてから調べた方が良いのかもしれませんが、量が少ないのでやってしまいます。
<Niagara SystemのScratch Module内にあるDynamic Material Parameter>
この変数の役割を調べようと思ったんですが、今の段階だと全て消してしまっています。ので調べようが無くなってしまいました。今回はPassします。
<Kill Particles In Volume>
Particle Update SectionでKill Particles In Volumeを使用しています。
このModuleについて調べます。
公式のDocumentであるParticle Update Group [5] には
と解説されていました。
Cursorを乗せた時と同じ解説でした。
この解説で言っている内容ではInterpolated Spawn が何を指しているのか分かりません。
それよりもGoogleでKill Particles In Volume UE4 Niagaraで検索しても
公式のDocumentが表示されないんですけど。
関係ないKill Moduleの公式のDocumentは表示されていますが?
試しにBingで検索してみたら
かなり下の方ですが一応 Particle Update Groupは検索に引っかかっています。
この場合はParticle Update Groupで検索するのが筋なのかもしれませんが、昔の方が検索の精度が良かった気がします。
<<Interpolated Spawning>>
Interpolated SpawningについてはEmitter Setting SectionのEmitter Properties Moduleにありました。
こんな説明がされていました。
要するにこれを使用した方がスムーズなParticleの生成が出来るけどその分コストもかかります。と言う事ですね。
現状、Kill Particles in Volume Moduleを使用して以下の様な状態になっています。
Interpolated Spawningのチェックを外します。
おお、本来発生してはいけない場所からもParticleが生成されています。
解説の通りですね。
<Initial Position変数をMap Getノードにいきなり追加出来ないのか?>
理由が分かりました。
以下に示した様にInitial PositionはMap Getノードからも
Parameterからも選択出来ないです。
だから先週、Transientを選んだ時と同じようなやり方をしてInitial Position変数をここにセットしたんでした。
はい。納得しました。
<BPを使用して球のActorの動きに合わせてParticleの発生を変化させる>
これ、実際にやってみたら分からない所は無かったはずです。
しかしBPからNiagaraを操作する方法を覚えておくのは大切なのでキッチリ復習します。
まず全体像を以下に示します。
BP側です。
Set Niagara Variableノードが使用されています。
このノードがNiagaraとBPを繋ぐ事を可能にしています。
Niagara側です。
敢えてUser ParameterをSystem Setting Sectionに作成しています。
このUser ParameterのみがBPからAccess出来る変数なのかは分かりません。その辺から調べます。
これを読むとその通りみたいですね。
gameDev Outpost 氏のTutorialにそのものずばりUE4 - Niagara Blueprints and User Parameters [6] がありました。
これ見たら、やり方全部説明していますね。
後、User ParameterのみがBPからAccess出来る変数かどうかは分かなかったですが、Niagara からBPとやり取りする時はUser Parameterを通してするのが普通のようです。
以上です。
3.Material : Ben Cloward氏のTutorialを勉強する
3.1 Min, Max, Clamp, & Saturate - Shader Graph Basics - Episode 11 [7]を勉強する
取りあえず軽く全部見ました。今回はUnityを主に解説していました。UEは最後に復習のためのちょろっとやっただけです。
流石にこれらのノードの使用方法は理解しています。と思ったらMinimumとMaximumの機能を反対に理解していました。
後、知らなかった事にSaturateと0と1をセットしたClampの違いがあります。Saturateを使用した場合はCostがFreeになりますが、Clampの場合は違うそうです。
実際にUE5を使用して試してみます。
MinとMaxをテストします。
Maxが黒を灰色に変化させているのは良く分かりますが、Minが白を灰色に変化させているのはあんまり良く分からないですね。
実際にスポイトで色を調べたら230になっていました。
255*0.8=204なのでLinearではないですが、Minが白の上限を設定しているのも確認出来ました。
次はSaturateの有り無しについてです。
無しの場合です。
有りの場合です。
うーん。正直分からん。
色をTutorialと同じにしてみます。
Saturate無しです。
Saturate有りです。
こっちの方が黄色味が薄いですね。
Unlitにしてみました。
Saturate無しです。
Saturate有です。
良く分かりません。
まあ理論的には-1の値をそのままLerpでPassすると変な色になってしまう時もある。と覚えておきます。
3.2 Blending Normal Maps - Shader Graph Basics - Episode 12 [8] を勉強する
最初にサラッと全部を見ました。このTutorialの内容を簡単にまとめます。
Normal MapについてとNormal Mapの混ぜ方についてです。Normal MapはTextureのVectorを保持しています。ので混合する時は色を混ぜるのと違って注意する点があります。更に混合方法を4つ紹介しています。四つの混ぜ方は、Simple、UDN、Whiteout、そしてRNMです。この講義ではそれぞれのCostについても説明しています。UnityのNormal Blendノードは設定によってWhiteout方式かRNM方式のBlendをします。UEのBlend Angle Corrected NormalノードはRNMと同じ役割をします。
それでは自分でもやってみます。
まずUnityとUnrealのNormal Mapの違いについてです。
Greenの値がお互いにInverseになっているそうです。
確認しようとしてUE5のTextureを開いたらBが外せません。
UE4でNormal mapを開いて見ました。
これだけ見ても差は分かりませんね。
TextureのDetailsに以下の項目がありました。
Unity用に作成されたTextureをUnrealで使用する際にはこの項目にCheckを入れるんですかね。
UE5でもこの項目はありました。
こっちのサンプルにはチェックがついていないので最初からUnreal用に作成されたNormal Mapと思われます。
完全にTutorialと同じには出来ないですが以下の条件で
こんなのを作成しました。
これを使用してTutorialと同じようにBlendingしていきます。
Tutorialが言う所のSimple Blendingを作成しました。
こんな結果になりました。
何で青が1なのかというかNormal Mapが一般的に言って青いのかが分からないとこの計算の意味が分からないです。
青はTextureの面に対しての垂直方向の軸を表しているんです。
Normal Mapにいくら凹凸があると言っても大体は平らなはずです。だから青いんです。
ただ、Textureの軸がどうなっているのか良く分かりません。
先週、勉強したTangent SpaceだとX軸が面に対して垂直に出ています。
正し、その図とMaterialのPreviewを見るとY軸の向きが逆です。
これらを見ると面に対して垂直に出ている軸はx軸で赤になります。がそしたらNormal Mapも赤くなる必要があります。のでWorld Spaceでいう所のXYZで言うとR = X、G = Y、B = Zとなっているはずです。
上記のMaterialのCoordinateだとZ = R, Y =G, X = Bになると考えられますが、ちょっとUV軸をZY軸に置き換えるのはあんまり聞いた事がないですので、保留しておきます。
兎に角、大体Normal Vectorは面に対して垂直なんだから青には1を入れとけば大体合っているわけです。
それがこのBlendingの本質です。
UDN方式のBlendingです。
UDN方式のBlendingは前のSimple 方式のBlendingだと岩のゴツゴツ感が無くなってしまう。と言う人向けに1の代わりの規定のNormal MapのBの値を使用します。
以下にSimple 方式でBlendした時のPreviewを示しておきます。
UDN方式のBlendingの方がゴツゴツしていますね。
UDN方式のBlendingは最後にNormalization(正規化)をしています。これは逆に何でSimple 方式のBlendingではNormalizationをしていないのかが不思議です。
Whiteout方式のBlendingです。
いやいや、それだったら規定のゴツゴツした岩だけじゃなくて小さい粒々だって考慮しますよ。
と言うのがこれです。
以下に比較のためのUDN方式でBlendingした時のPreviewを置いておきます。
確かに粒々もはっきりしています。
RNM方式によるBlendingについてです。
Tutorialのまま、Copyしました。
Tutorialによると何でこういう計算をするのかについてはここでは説明しないので以下にLinkを貼っておくとありました。
多分、これ(Blending in Detail)と思いますが、ぱっと見た感じではRNMの説明は無いように見えました。
正確な計算や計算の理論はOpenGLなどの教科書を見れば載っているでしょう。ここは3D graphicsとUEのMaterialの理論が一致しているのが大切です。
今週も、もう一個Tutorialをやる時間は無くなってしまいました。ここでMaterialの勉強は終わりにします。
4.NPCのAIを作成するためのAIの復習の続き
先週、終わらなかったDebug機能を使用したDecorator ノードのObserver Abortの機能の解説を行います。
4.1 Observer Abortの機能の解説のDebug
<None>
Decorator ノードのObserver AbortがNoneにセットされている場合の変化をみます。
Observer AbortがNoneにセットされているDecorator ノードであるBlackboard Based Conditionの条件が満たされているためPrint String1が実行されます。
Print String1が実行されるとSuccessを返します。返された親ノードはSequenceであるから、Failが返ってくるまで子ノードを左から右へ実行します。
のでPrint String1を実行します。
Print String1の実行が終わるとSuccessを親クラスであるSequenceノードに返します。するとSequenceは全部の子ノードがSuccessを返したのでSuccessをその親ノードであるSelectorに返します。Successを一個でも返されたSelectorは子ノードの実行を中止してその親ノードであるRootへ返します。
これを何度も繰り返すだけですが、ある時Print String1を実行中にDecoratorの条件が変化してFalseになりました。
Decorator ノードのObserver Abortの設定によって、ここからの挙動が全く変化します。
まずNoneにセットしていた場合です。
以下のPrint された文字を見れば分かりますが、Print Stringが実行され、Print String1が実行中にDecoratorの条件が変更されました。
Print String1の内容は全て実行され、その後Rootにまで戻ります。
Decoratorの条件が変わらなかった時と全く同じです。何事も無かったように行動します。
以下に示したPrint String1(Execute)がPrint String1を最後まで実行した事を示しています。
そして次のTurnから新しい条件のDecoratorで実行されます。
これがDecoratorのObserver Abortの設定をNoneにした場合です。
<Self>
今度はSelfにセットした場合です。
以下に示した様に、Print String1を実行している時にDecoratorの条件が変化してFailになりました。
AIはPrint String1の実行をただちに中止します。
以下に示したようにPrint String 1ではAbortが実行されています。
するとPrint String1はFailを親ノードであるSequenceに返します。
SequenceはFailを受け取ったのでそれ以上の子ノードの実行を中止します。
更にSequenceの親ノードであるSelectorにFailを返します。
Failを受け取ったSelectorは次の子ノードを実行します。
これがSelfです。Noneとの違いは実行しているTaskを中止するかどうかです。
<もう一回Self>
よしSelfとNoneの違いが分かった。と早とちりしないで下さい。以下の条件でもう一回テストします。
今度は、最初はDecoratorの条件を満たしていないのに、Print String3を実行中にDecoratorの条件を満たした場合です。
はい。Abortが発生していません。
Debugを見ても
Abortが発生していません。
最後まで実行しています。
その後、新しいturnに入ってからDecoratorの条件にそって別のTaskを実行してます。
これってNoneと同じじゃないですか?
はい。
SelfがAbortを実行するのは、Decoratorがあるノードの子ノードに対してだけなんです。
Decoratorがあるノードと同じ親ノードを持っているがDecoratorがないノードを実行している時にDecoratorの条件が変化しても何も反応しません。Noneである場合と同じようにずっと定められた内容を実行します。
ではDecoratorがないノードを実行している時に、Decoratorの条件が変化したらAbortしてほしい時はどうしましょう。それを可能にするのがLower Priorityです。
<Lower Priority>
今度は先程と同じ条件ですが、Decoratorの条件をLower Priorityに変更します。
Print String3を実行中にDecoratorの条件が満たされると、Print String 3の実行を中止してAbortを発します。
Debugを見ると
いきなり以下のように変化しています。
ここでPrint String 3からSequenceそしてSelectorへの赤いlineが現れないのは良く分からないです。
<Both>
では何時でもDecoratorの条件が変わった時にはAbortしてほしい時にはどうしますか?
その時はBothを使用します。
4.2 応用編について
今回は、応用編は作成しないつもりでしたが、そうするとNPCのAIが作れないので、応用編も作成する事に変更しました。
応用編は
- AI Perceptionについて
- EOSについて
についてやるつもりでしたが、これだけだと不十分です。
もう少し基礎的な、例えばNav Mesh Bound Volumeの使用方法などの解説が必要です。
それで基礎編2、応用編1、応用編2に分割しようと思います。
それで、内容なんですが今までUE4_AIで勉強した
- Ryan Laley氏のAI [9]
- Mathew WadsteinのWTF Is? AI [10]
- そしてOnline LearningのIntroduction to AI with Blueprints
の内容を基礎編2、応用編1、応用編2に分割して整理してまとめようと思っています。
Online LearningのIntroduction to AI with Blueprintsの内容に関しては、2021-02-01のBlogでそれぞれの講義を簡潔にまとめています。
因みに公式のDocumentであるArtificial Intelligence [11] では、以下に示した様にUE4のAIを5つの分野に分類して説明しています。
ちょっとBehavior Treeだけ見てみます。
あ、
読んでいて何で私が敢えてAIのTutorialを自分で書き出したのかを思い出しました。
この公式のDocumentの説明でUEのAIの仕組みが理解出来なかったからでした。
逆に言うと私が作成した基礎編のTutorialさえ理解出来れば、後は、公式のDocumentやYouTubeにあるTutorialを見てUE4のAIについての見識を深める事が可能なので、これ以上私がTutorialを作成する意味はない訳です。
うーん。
良し。こうします。
オリジナルのTutorialを作成するしないに関わらず、NPCのAIの作成をするのに
- Ryan Laley氏のAI [9]
- Mathew WadsteinのWTF Is? AI [10]
- そしてOnline LearningのIntroduction to AI with Blueprints
- 公式のDocumentであるArtificial Intelligence [11]
の復習は必要です。
今週はこれらのTutorialの最初の部分を復習しながら、何で私がオリジナルのUE_AIのTutorialを作成しないといけなかったのかとか、何でそのTutorialの説明だと理解出来ないのかなどを解説しながらまとめたいと思います。
4.3 新しいUEのAIのTutorialが出ていないかチェックする
自分が知らない間に完全無欠なUEのAIのTutorialが発表されているかもしれません。それをちょっとだけ調査します。
LeafBranchGames氏のAI [12] がありました。
最初のTutorialが発表されたのが2021年の8月です。出来立てほやほやです。
これもチェックする事にします。
公式のOnline Learningもチェックしましたが特に新しいTutorialが発表されたとかは無かったです。
5.UEのAIのTutorialの勉強
今週はそれぞれのTutorialの最初の2、3個だけチェックします。
5.1 公式のDocumentであるArtificial Intelligence [11]の勉強
このPageを開いたAI初心者が最初に選ぶのはBehavior Treeだと思うのでBehavior Tree内のTutorialから試してみます。
UE_AIをこのような分類にしているのはかなり正しいと思います。自分がUE_AIのTutorialの最初の部分をまとめた時、Navigation Systemが入り込む余地がなかったです。更にAI Perception
とEQSを分けているのも正しい分類と思います。AI Debuggingにおいては言語設定が違う時のDebugの仕方がきちんと解説されているのかが気になります。
今回は、最初のTutorialであるBehavior Treeを見て行きます。
<Behavior Trees [13]の勉強 >
Remarkに以下の説明がありました。
イキナリBehavior Treeの説明から入っているので、AIとBehavior Treeの関係が良く分かりません。
ビルの建設で一階を立てる前に、2階を建設しているような気分になります。
後、BlackboardをBehavior Treeの脳に当たると紹介していますが、これは間違っています。BlackboardはBehavior treeのために変数の値を保持する機能しか持っていません。勿論記憶するのは脳の大事な役割の一つですが、人間の脳には他の重要な役割も沢山あります。
こういう偽人的な例えは、AIらしさを強調するには役立ちますが、学習者がUE_AIを理解するためには大変な害になります。
ここははっきりと「UEのAIは単なるIF節である。」と言うべきです。
以下のTutorialに分かれていました。
勿論、今回は最初のBehavior Tree Quick Start Guide [14]をやってみます。
<<Behavior Tree Quick Start Guide [14]を勉強する>>
以下に示したRemarkによると、いきなりPatrolやPlayerの操作するキャラの追跡をするAIを作成するみたいです。
何で、前のPageでNavigation Systemを分けたのか全く分からない仕様になっていますね。
先に進みます。
このTutorialを勉強すると以下の事が理解出来るとあります。
最初のBP云々は兎も角、この選択は素晴らしいです。私が作成したUEのAIのTutorialで解説している要素とほとんど同じです。
このTutorialではNPCが抜けています。
何故このTutorialを作成した人はNPCは重要でないと思ったんでしょうか?
その辺も行間から感じながら勉強していきます。
普通にNPCをThird Person Characterをcopyして作成しています。そこに新たに作成したControl AIをセットしています。
やり方を勉強するには非常に分かり易いです。しかしControl AIとThird Person Characterの関係性についての解説は一個もありません。作品は完成しますが、学習者が何も理解出来ない、AやってBやってCやってTutorialの典型です。
正し、このTutorialをやるだけで、Task内の実装や、Perceptionの実装のやり方まで勉強出来ます。そういう意味ではかなり優れたTutorialです。
UEのAIは理解していたけど何カ月も触ってなくてやり方を忘れてしまった人には非常に良いTutorialです。
今週は他のTutorialも見る必要があるので実際には試しませんが来週実際にやってみます。
Behavior Tree Quick Start Guide [14]にあった他のTutorialも見てみます。
<<Behavior Tree Overview [15] の勉強>>
軽く見ておきます。
まず、全体的な感想ですが、UEのAIの基本を既に理解した人がBehavior Treeに関する知識を更に肉付けしたい時に読むには、とても良いです。
私が「この説明は納得。」とか「この解説は分かり易い。」と思う部分がそこかしこにありました。
いくつか例を挙げると
青色の部分ですが、AIだってBPで作成出来るけど、Behavior Treeを使用してAIを作成するとこんな点で便利です。
と言外で言っているように私には読めました。
これは私のUEのAIのTutorialの思想と一致しているとも読めます。
Blackboardの機能を情報を保持する事。とはっきり述べています。脳の働きなんで訳わからん事は言っていません。
この辺なんか単なる読み物としても面白いです。
<< Behavior Tree User Guide [16] の勉強>>
このTutorialはBehavior TreeやUEのAIに関連したクラスの作成方法や使用方法を一個一個、細かく丁寧に解説していました。
これはこれで大切です。
Composite Decoratorについて解説してる箇所がありましたが、この機能は初めて知りました。
<<Behavior Tree Node Reference [17] の勉強>>
UE4_C++でBehavior Treeに追加のコードを書く時には、必要な情報かもしれませんが、今のLevelでは必要ない情報です。
<公式のDocumentであるArtificial Intelligence [11]の感想>
今回は、この中のBehavior Trees [13]の勉強 のみをやりました。
やはり、公式のDocumentだけあってLevelが高く、読み応えがある内容が多かったです。
しかし私が提唱している「UEのAIは単なるIF節」という思想を明確に示している箇所はなく、UEのAIを全く勉強した事がない人がイキナリ読んでも途中で理解出来なくなる可能性は高いと思われます。
学習者が私のTutorialで勉強した後でこのDocumentを読むなら、大変役立つ内容に成っていると思いました。
5.2 Online LearningのIntroduction to AI with Blueprintsの復習
Introduction to AI with Blueprintsをもう一回勉強します。
2021-02-01のBlogに勉強した内容を簡潔にまとめてあるのでそれも参考にします。
さくっとですが2021-02-01のBlogにあるIntroduction to AI with Blueprintsの最初の2~3個の講義のまとめを見直しました。結構本格的なAIの解説が中心の講義をしているみたいです。
今回の話で特に関係しているのは以下の部分ですかね。
みました。
5分で終わってしまいました。
なんでこんなに沢山の講義を一日で勉強出来たのか不思議だったんですが、一個の講義が短かったんですね。
内容に関しては前の感想と同じです。
後、びっくりしたのはこの講義、日本語の訳が付いていました。こんな所まで翻訳してあるんですね。
5.3 Mathew Wadstein氏のWTF Is? AI [10]
BPでノードの使用方法が分からない時に、いつもお世話になっているMathew Wadstein氏のAIのTutorialです。
これは見た事がないですね。この構成から想像すると最初のSimple Move in Unreal Engine 4で公式のDocumentでいう所のBehavior Tree Quick Start Guide [14] をやっているみたいです。
その後、徹底的に基礎の解説をしていますね。
じっくり見てみます。
<WTF Is? Simple Move in Unreal Engine 4 ( UE4 ) [18] の勉強>
全然、想像と違いました。以下に示しましたが、
Behavior Treeを使用しないAIの作成を行っていました。
うーん。これは私の想像を超えてました。こっちからAIの勉強に入る方法もあるんですね。
ここで、AI ControllerとNav Meshについての解説を終えています。これはこれで凄いです。
<WTF Is? AI: Blackboard in Unreal Engine 4 ( UE4 )[19] の勉強>
今度はBlackboardについてです。これだけは昔見た事があるみたいです。内容は全く覚えていませんが。
Videoが8分有ります。BlackboardなんでBlackboard key(変数)の作成方法とそれをBehavior Treeから呼び出す方法、もしくはAI ControllerなどのBPから呼び出す方法位しか勉強する事無いと思うんですが、何を8分も講義するんでしょうか?
見てみます。
最初はBlackboardがBehavior Treeのために値を保持するObjectであると説明しています。
これはその通りですが、Behavior Treeの説明もない状態で言われても初心者にはチンプンカンプンかもしれません。
それだけじゃなくて実際にBehavior Treeを開いてさらにSelector、Decorator、そしてServiceまで使用してBlackboardの使用方法について解説しています。
これは結構、初心者にはきついかもしれませんね。Mathew Wadstein氏のTutorialは分かりやすく、いつもお世話になっていますが、ここはBehavior Treeを先にやった方がもっと分かり易かったと思いますね。
そんだけですね。
Blackboardの使用方法やBehavior TreeからBlackboard keyを呼び出す方法の説明はとても分かり易かったです。
<WTF Is? AI: Behavior Tree in Unreal Engine 4 ( UE4 ) [20] を勉強する>
DecoratorやTask、Serviceなどの簡単な使い方を含めてBehavior Treeの仕組みを説明していました。
この中にSimple Parallelと言う知らないCompositeがありました。
最後にこの後、Behavior Treeで使用する一つ一つのクラスの解説をこの後でそれぞれ独立して行い、それが終わったらまたBehavior Treeに戻ってもう一回全体の使用方法を解説するとありました。
物量作戦です。感服です。
5.4 Ryan Laley氏のAI [9] の勉強
Ryan Laley氏のAI [9]で今回、勉強しなければならないのは一番最初のTutorialだけです。何故なら2番目のTutorialはPerceptionの説明に入ってるからです。
<Unreal Engine 4 Tutorial - AI - Part 1 The Behavior Tree [21] について>
結構しっかりと4つのクラスからAIを作成する方法を説明しています。
良く考えたらこのTutorialでUEのAIについて勉強したんで、私のUEのAIに対する考え方がこのTutorialと似ているのは当たり前でした。
そんだけです。
5.5 LeafBranchGames氏の AI [12]について
LeafBranchGames氏の AI [12]は最初からPerceptionについての話題なので今回はパスします。
来週見ます。
6.World CompositionによるMap1の作成
先週、やったMap1へのWorld Composition化を実際のゲームであるch4_3のMap1で行います。
6.1 Landscapeの作成
Enable World Compositionをチェックします。
以下の注意が出て来ました。
うえ。マジか!
一端、Cancelします。
Map1とmap1_BuildDataを別なFolderに移しました。
もう一回、Enable World Compositionをチェックします。
今度は警告されませんでした。
以下の様になりました。
今のLandscapeの配置を見ると以下に示した様に少し中央からずれています。
15マスと
0.8マス
下にずれています。
真ん中に64x64のLandscapeが配置されるとなると32mはみ出すのが正しいので、15.8mしかはみ出していないとも言えます。
新しく作成するLandscapeは16.2m上にずれる訳です。
今度は左右を見てみます。
もう少し細かく見てみます。
10マスにギリ足りません。
拡大します。
0.7マスと
0.04マス位でしょうか?
9.74m右にはみ出しています。
本来は32m右にはみ出さないといけないので22.26m左にずれているとも言えます。
ActorのLocationはcmが単位なはずです。
Map1に存在する全てのActorをxに+2226、yに‐1620ずらせばぴったし合うはずです。
うーん。
何か間違っている気がします。
Y軸をもう一回確認します。
Actorを配置してそのActorの位置を測定する事にします。
Y軸に対して1480でした。
3200‐1480=1740です。
左右も同じ方法で測定します。
9.74mずれています。
こっちの計測は合ってましたね。
最初からこのやり方で計測すべきでした。
それではLandscapeを作成していきます。
計算値とは違うですが以下の値で設定する事にしました。
Landscape内の値。
World SpaceにおけるこのLandscapeの値。
さっきのActorにぴったし合わせたらこの値になりました。
後、前回はこのLandscapeを作成する時に位置を指定しなかったから後で直せなかったんだと分かりました。
作成します。
ああ、ずれています。
やり直します。
今度は計算値でやります。
X軸は合っていますが、Y軸はもう少し下です。
色々試したら以下の値がもっとも合っていました。
これでやってみます。
World Compositionを開くと以下の様になっていました。
ただしこれはLevel1_1のLandscapeなので上に一個、左に4個ずらす必要があります。
しました。
前のLandscapeと合わせるとバッチし合っています。
これでいきます。
36個のSub Levelを追加しました。
前のLandscapeと位置が完全に一致しています。
Height MapをImportしました。
LandscapeのLandscape MaterialにMap1_instをセットします。
LandscapeのPaintのLayersに以下に示した値をセットしました。
36個のLandscape Streaming Proxyの
Landscape MaterialにMap1_instをセットしました。
こんな感じです。
こんな感じです。
まあいいんじゃないでしょうか。
SD_10Kを作成して全てのSub Levelをそこに移しました。
今までのLandscapeは要らないので消してしまいます。
Playして試してみます。
落ちて死にました。
ひょっとしてLandscapeの高さって0じゃなかったんでしょうか?
うーん。
前のLandscapeはもう消してしまっています。
Map1_testがありました。こっちの値を調べて見ます。
100ですね。
成程、確かにみんな浮いています。
浮いていますがこれ位の高さかならLandscapeが見えないのはおかしいです。
これはLandscapeが生成されていないように見えます。
逆にもう少し高くに発生させて確認します。
にしました。
落ちている間に地面が誕生しました。
静的に配置されたActorが全て浮いています。
静的に配置されたActorの位置を全て100cm下げます。
直しました。
後、Monsterなどの動的に生成するActorは生成しないようにしました。
Itemもです。
これでテストしてみます。
こんな感じです。
奥のLandscapeが読み込まれます。
色々な場所を散策しましたが結構PCは熱くなってるみたいでファンがうんうん言っていました。
6.2 ActorをそれぞれのSub Level内に分割して配置する
これも先週と同じやり方でやります。
出来たので試してみます。
大体良かったのですが変なLandscapeが表示されています。
山が出来ると消えます。
なぜこうなるのか分かりません。
これはそのSub Levelに属するActorがはみ出している場合はLevelのサイズが変わるみたいで、バグではなさそうです。
更に以下の様になってゲームが始められなくなってしまいました。
原因が分かりました。
World Compositionで読み込んだ場合、Landscapeが作成されるのが遅いんです。
Planeを置いておいてCharacterが落ちないようにしないといけません。
色々遊んでみます。
6.3 World Composition来週以降の課題
まず以下に示した、変なTextureを伸ばした様な絵Landscapeが表示される時があります。
これの直し方が分かりません。
World CompositionはLandscapeの読み込みが速いのが特徴ですが、以下に示した様にLandscapeの読み込みが始まる前に1秒程度の遅れが生じます。
この二つは商用レベルのゲームではあってはならないバグですが、直し方が分かりませんでした。
来週、もう一度検討します。
7.UE5におけるWorld Partitionの勉強
7.1 公式DocumentのWorld Partition [22] を勉強する
最初の導入部の文章で以下の解説がありました。
この「手動でSub Levelを分割して、Level Streamingを使用してLandscapeをLoad したりUnloadしたりしていた。」と読めますが、World Compositionの事を指していない、つまり単なるStreaming Levelの事を述べてるように感じます。World Compositionを使用すれば、手動でLevel Streamingを組む必要がないからです。
SeamlessなLevelのLoadingは今のゲームではかなり重要なPointですが、この分野の教材はあまり整理されていないのかもしれません。
World Partitionは以下に示した4つ特徴があるそうです。
それぞれが何を指しているのか全く想像出来ませんね。
<Enabling World Partition in Your World>
最初の章です。
World Partitionの使用方法についての説明をしているみたいです。
これは先週勉強した内容と一致しているはずです。
復習を兼ねて読んでいきます。
World Partitionの使用方法の説明ではなく、World Partitionが使用可能になるための設定方法についての説明でした。
2つの方法が紹介されていました。
最初の方法は、Project Settingから設定する方法で、先週やったやり方と同じです。もう一つはCommand Promptから指定する方法でした。
Command Promptから指定する方法は、必要になった時に勉強する事にします。
<Using World Partition>
今度こそWorld Partitionの使用方法の解説です。
と思ったら、最初はWorld Partitionの特徴を説明しています。
最初の文ですが「PersistentなLevelが一個だけあってそれに沢山のSub Levelがあります。」と書かれています。でもこれってWorld Compositionでも同じですよね。特別、World Partitionだけの特徴とは言えない気がします。その後の解説であるConfigurable Runtime Gridを使用して、Persistent LevelをStreamable Grid Cellに分割してる所がWorld Partitionの特徴なんでしょうね。
ここでは、Configurable Runtime Gridが何であるかの説明はありませんが、名前から察するとRun time中にSub Levelを指定する技術のようです。もしそうなら大変な技術革新です。Configurable Runtime Gridには注目していきます。
次の文では「Playerが見たり、干渉したりするSub LevelだけをLoadします。」と解説されています。これってLoadされるLevelは単にPlayerからの距離だけではなくPlayerから見えるSub Levelは遠くのLevelでもLoadされると言う事でしょうか?
もしそうならWorld Compositionよりだいぶ改良されていますね。この辺も注目していきたいです。
<<Actors in World Partition>>
World PartitionがEnableされた後は、配置されている全てのActorにGrid Placementの指定が出来る様になるらしいです。
試しに先週作成したWorld Partitionに配置されているActorを見たら以下のような設定が載っていました。
Grid PlacementがLocationに設定されています。
Documentの説明を読むと
と書かれていました。
これを理解するのに、前提条件としてUE4のWorld CompositionではどのActorがどのSub Levelに属するかと手動で指定しています。
この部分をUE5のWorld Partitionは自動でやってくれます。
正し、どのような方法でSub Levelに分類されるかはActor毎に指定出来る訳です。
その指定方法が、World PartitionのGrid Placementなんです。
ここでLocationを指定すると
という条件でActorは配置されるGrid Cellを選択出来ます。
ただしこの条件で言っているBounds Volumeが何を指しているのかが分かりません。
このBounds VolumeがActor内にあるのか、Grid Cell内にあるものなのかすら分かりません。しかもこのBounds Volume、Theirで修飾されています。ActorにしてもGrid Cellにしても単数です。
うーん。
あ、分かりました。「the Actor」とActorのAが大文字で書かれているから、これが複数を表しているんです。となるとContainsは3人称単数なので必然的に、The Grid Cellを指します。はい。
つまり、Actor内にBounds Volumeがあってその中心もある。まあ多分Actorの重心みたいなのがあるんでしょう。その点が配置されているGrid CellにそのActorも属する事になると言っているわけです。
上記のWorld Compositionの例で言えば、以下に示した岩、はこのSub Levelに部分的にしか入っていません。この岩をどのSub Levelに属するのかを決めるのは、手動でも結構悩みます。
それをそのActorが持つBounds Volumeの中心(多分重心みたいなもの)が配置されているThe Grid Cell(UE4のSub Levelに当たるもの)に属すると決めるのがLocationなんです。
多分、この解釈で合っているでしょう。
確認のために他の選択肢も見てみます。
はい。まず「All the grid cells that intersect…」とあります。つまりGrid Cellが沢山ある前提の話なんです。それは以下に示したようなActorがSub Level(UE5ではThe Grid Cell)の境界上に配置された場合について言っている訳です。
この時点で、私のLocationに対する解釈はほぼ正しいと確信しました。
World PartitionのGrid PlacementはActorがGrid Cellの境界上に配置されていた時に、どこのGrid Cellに属するかを指定するためのものだったんです。
別にGrid Cellの境界上に無い場合はそのGrid Cellに属するのは当たり前なんです。だからそんな事は指定しない訳です。
何で今度は「its bounds volume」と単数形なんでしょうか?
でもこれでBounds VolumeがGrid Cellを指していない事はほぼ確実ですね。この文章ではGrid Cellsと複数形になっていますから。The Actorだから書き手の心に描いている状況によって複数だったり単数だったりするのかもしれません。
細かい点ではまだ不明な所がありますが、Boundsを選択した時は、このActorは全てのGrid Cellsに含まれると言う説明で間違いないでしょう。
どのGrid Cellが読み込まれてもこのActorは表示される訳です。
でもこれってあるActorが4つのGrid Cellにまたがって配置されていて、その内の一つのGrid Cellが読まれた場合は良いんですが、4つ全部のGrid Cellが読まれた場合はどうするんでしょうか?
勿論、そこは最新のTechnologyを有するEpic Games社が開発したWorld Partitionですから一個のActorしか読み込まれないんでしょうが、どうやっているのかとても不思議です。
<Streaming Sources in World Partition>
ここで言うStreaming SourcesはPlayerが操作するキャラの事のようです。
Streaming Sourcesが在る場所の周りのGrid CellsがLoadされるという極めて当たり前の事が説明されていました。
ここに書かれているそれ以外の情報については、曖昧な点が多いので、一応読みましたがここにまとめるのは今回はPassしておきます。
<Changing the Runtime Grid Settings>
ここは先週もやったGrid Cellの設定についてです。
先週の解釈では
と述べています。
この辺の確認もしたいですね。
その通りでした。
Documentに乗っているサンプルではCell Sizeが3200、Loading Rangeが25600なので単位はcmのようですね。
単位はUE4のWorld Compositionなどと同じですね。Unreal Unit(1cm )というやつですね。
<Loading and Unloading Grid Cells in the Editor>
Level上に配置されているActorやLandscape(多分)を編集する時に、Map上に表示する必要があります。その方法についての解説などでした。
<その他の項目>
残りの項目は今の私にはそんなに重要じゃないので読むだけにしておきます。
8.Loading Screenの勉強の続き(Moduleについて)
時間的にLoading Screenの勉強をこれ以上する事は出来ないので、やりたかった内容をここにまとめておきます。時間に余裕が出来た時にやろうと思います。
- ModuleとPlug Inの違いについて
- Visual studio でC#で管理しながらC++を呼び出す場合、UE4のようにModuleを作成してやっている気がします。これについて調査したかったです。
- Async Loading Screen PluginではOpen Levelノードが呼ばれるたびにPlugInが呼ばれるようになっています。その設定方法を知りたかった。
まあしょうがないですね。
今回はこれらの事は諦めます。
9.まとめと感想
今週は、World Compositionを実際のGameに応用するのでほとんどの時間が取られてしまいました。現在、World Compositionに発生している2つのバグは何とかして直したいです。
Niagara はCGHOW氏のTutorialでも普通に理解出来るようになって来ましたね。勉強の成果が出て来ていると思います。
Materialの勉強ではとうとうOpenGLで勉強した3D Graphicsの知識が一致して来ました。
UEのAIの復習はもう少し時間がかかりそうです。
World Partitionはもう少し勉強しないと全体像が分かりませんね。
以上です。
最近になって、やっとUEの全体像が分かっていた気がします。
10.参照(Reference)
[1] CGHOW. (2021, September 20). Disintegration in UE5 Niagara Tutorial | Download Files [Video]. YouTube. https://www.youtube.com/watch?v=4dYg4bvf4Rc
[2] Epic Games. (n.d.-h). Particle Spawn Group. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Niagara/EmitterReference/ParticleSpawn/
[3] Epic Games [Unreal Engine]. (2020, May 27). Building advanced effects in Niagara | Unreal Engine [Video]. YouTube. https://www.youtube.com/watch?v=syVSRDQxrZU
[4] Epic Games. (n.d.-g). Image Adjustment. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Materials/Functions/Reference/ImageAdjustment/
[5] Epic Games. (n.d.-I). Particle Update Group. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Niagara/EmitterReference/ParticleUpdate/
[6] gameDev Outpost. (2020, September 26). UE4 - Niagara Blueprints and User Parameters [Video]. YouTube. https://www.youtube.com/watch?v=JeMbHxU4TD0
[7] Cloward, B. C. [Ben Cloward]. (2021a, August 19). Min, Max, Clamp, & Saturate - Shader Graph Basics - Episode 11 [Video]. YouTube. https://www.youtube.com/watch?v=Eux84hotIwY&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=11
[8] Cloward, B. C. [Ben Cloward]. (2021b, August 26). Blending Normal Maps - Shader Graph Basics - Episode 12 [Video]. YouTube. https://www.youtube.com/watch?v=GKVBJ7aO1Mk&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=12
[9] Laley, R. L. (n.d.). AI. YouTube. Retrieved October 17, 2021, from https://www.youtube.com/playlist?list=PL4G2bSPE_8ukuajpXPlAE47Yez7EAyKMu
[10] Wadstein, M. W. (n.d.). WTF Is? AI. YouTube. Retrieved October 17, 2021, from https://www.youtube.com/playlist?list=PLSlkDq2rO1t47gMJ0GdO5aSTfOKy_TTln
[11] Epic Games. (n.d.-a). Artificial Intelligence. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/
[12] LeafBranchGames. (n.d.). AI. YouTube. Retrieved October 17, 2021, from https://www.youtube.com/playlist?list=PLNBX4kIrA68lJZIdFOpWqqY7d4ehjVKMx
[13] Epic Games. (n.d.-f). Behavior Trees. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/
[14] Epic Games. (n.d.-d). Behavior Tree Quick Start Guide. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeQuickStart/
[15] Epic Games. (n.d.-c). Behavior Tree Overview. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreesOverview/
[16] Epic Games. (n.d.-e). Behavior Tree User Guide. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeUserGuide/
[17] Epic Games. (n.d.-b). Behavior Tree Node Reference. Unreal Engine Documentation. Retrieved October 17, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreeNodeReference/
[18] Wadstein, M. [Mathew Wadstein]. (2016a, March 1). WTF Is? Simple Move in Unreal Engine 4 ( UE4 ) [Video]. YouTube. https://www.youtube.com/watch?v=zy7LcHPxVfU&list=PLSlkDq2rO1t47gMJ0GdO5aSTfOKy_TTln&index=1
[19] Wadstein, M. [Mathew Wadstein]. (2016c, March 2). WTF Is? AI: Blackboard in Unreal Engine 4 ( UE4 ) [Video]. YouTube. https://www.youtube.com/watch?v=CSxL29dX4i8&list=PLSlkDq2rO1t47gMJ0GdO5aSTfOKy_TTln&index=2
[20] Wadstein, M. [Mathew Wadstein]. (2016b, March 2). WTF Is? AI: Behavior Tree in Unreal Engine 4 ( UE4 ) [Video]. YouTube. https://www.youtube.com/watch?v=bsDT95UdPbc&list=PLSlkDq2rO1t47gMJ0GdO5aSTfOKy_TTln&index=3
[21] Laley, R. [Ryan Laley]. (2019, January 17). Unreal Engine 4 Tutorial - AI - Part 1 The Behaviour Tree [Video]. YouTube. https://www.youtube.com/watch?v=zNJEvAGiw7w&list=PL4G2bSPE_8ukuajpXPlAE47Yez7EAyKMu&index=1