UE4の勉強記録

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

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する Open Worldの検証

f:id:kazuhironagai77:20220206214811p:plain

<前文>

<MANGA

Tech 系の記事を読んでいたらコメント欄でMangaと書かれていました。マンガの事かと思ったらMeta、AmazonNetflixGoogle、そしてAppleの事でした。初めてそんな言い方を知ったんですがFacebookが名前をMetaに変更した(する?)のでそういう呼び方をするようになったそうです。

勿論、日本のマンガにかけて敢えてそう呼んでいるはずです。

そしてどうやらMangaと言う言い方を好んで使用してるのがどうもFacebook系の人達のようなんです。

先々週ぐらいの前文で、FacebookのMetaverseは失敗すると思うと書きました。その原因の大きな一因として日本のアニメの影響を無視した3Dモデルを使用してるからだ。と書きましたが、そのFacebook系の人達があえて自分達をMangaと呼ぶと言う事はMetaverseの成功は日本のアニメや漫画文化とどれぐらい融合出来るのかにかかっているとやっぱり考えてるんだなとも思いました。

アメリカのz世代は、日本のアニメや漫画を宗教のように崇拝して日本人より詳しいぐらいです。

その連中の興味を引くためには、敢えて自分達の事をMangaと呼ぶ位の事はしないといけないと思っているんでしょうね。

でもそんな付け刃が通じるかどうか?

どうなんでしょうね。

やっぱりFacebookはウルトラ右派と共に沈む運命が待っている気がしますね。

ウルトラ右派は結局、人種差別主義者やナチズムの信望者が、嘘をつきまくってまるで愛国者のふりをしているだけだったんです。最近になってやっとその事が一般人の目からも明らかに成り始めました。

まあ、そういう連中とずっと付き合ってやって来た訳で、とんでもない負のカルマがFacebookにはくっ付いている気がしますね。

<日本政府はアニメや漫画に敬意を払うべきだった>

Metaverseが成功するかどうかは一端置いとくとして、アメリカ側から日本にアニメや漫画の専門家を紹介してほしいと言われてたらどうするんですかね。

日本人が知らないアメリカですが、アメリカって日本とは比較にならないくらい推薦を重んじる国なんです。でもこれは裏返しに推薦する人の責任も重大になります。

日本政府が紹介したアニメや漫画の専門家がアメリカ側の要求に耐えれるLevelの人物じゃなかった場合、推薦した日本政府に対して滅茶苦茶怒ってくると思います。

ジャンプの黄金時代辺りに、国立の美大にアニメ科や漫画科を創設しておけばそういう事態に対応出来たかもしれません。まあ30年遅かったですね。

日本政府はもっとアニメや漫画に対して敬意を払うべきだったです。

というか国立の美大に今までアニメ科や漫画科が無いと言う事は、日本政府は漫画やアニメを芸術として認めていないと言う風に海外から見られますよ。

そしてそれは著作権の問題にも直結する気がするんですが、どうなんですかね。

著作権はIntellectual propertyにつくもので、知性的じゃないものにはつかないんです。私は法律の専門家ではないですが、海外、特にアメリカでは、この知性的であるかどうかを判断する基準において、大学で教えているかどうかってかなり大きなPointになってるはずです。

例えば、アメリカの大学だと映画やComputer Gameは専門の学科があります。そこで勉強した人達がその産業に就職するわけです。

私は法律の専門家じゃないですが、アメリカでガチのアニメや漫画の著作権の裁判になったら、この辺はマジで突っ込まれる気がするんですが。

<あるアメリカ人YouTuberのHxHについての考察>

ちょっと昔過ぎて、どのYouTuberが言っていたのか忘れてしまったんですが、あるアメリカ人YouTuberのHxHの考察で非常に考えされるものがあったんです。

それを要約すると、ゴン(HxHの主人公)の規範は常にGoodかどうかで決まっていて、決してRightかどうかを問題にしていない自分勝手な規範であると。

Stanford business school の教授だったJim Collins氏のGood to Greatを読んでGood とGreatの違いは知ったつもりになっている私ですが、そんな私でもGood とRightは同じ意味だと思っていました。焦って英英辞典で調べたらGoodの意味にRightであると書かれていて、Right の所にもGoodである事と書かれていました。

あれ。と思って話を更に聞くと、その人もHxHを見るまでは同じと思っていたそうです。

その人の解説を聞くとGoodには自分にとって良い事が大前提なんだそうです。言われてみればGood for youとは言ってもRight for youとは言わないです。Goodには自分にとって良い事である事が前提として含まれています。それに比べてRightには自分に取って得かどうかは関係ないです。と言うかRightな事をすると自分に不利益になる事は多々あります。

これがGoodとRightの違いだったんです。

それでHxHの主人公であるゴンが意思決定をするのは常にGoodかどうかが基準でRightかどうかは基準じゃないと言っていたんです。

そしてそれは最後にゴンが怒りに任せて変身して敵を殺してしまう所で、読者は気が付くんだと。GoodとRightが違う事に。

この解説には流石に納得しました。称賛するしかない文句のない解説でした。

正直、ゴンが怒りに任せて変身して敵を殺してしまうところで、私はDragon Ballスーパーサイヤ人の真似だとは思いましたが、GoodとRightが違う事なんで考えもしませんでした。そんなに深く考察しながらアニメを見た事はなかったです。

でもその解説を聞いて、その後のHxHの展開が凄く納得いったんです。

ゴンが怒りに任せて変身して敵を殺してしまう所でGood とRightの違いに気づいたのは読者だけじゃなかったんです。主人公のゴン自身もそうだったんですよ。そしてその瞬間、ゴンは自分を捨てた父親を許せたんだ。と思いました。

自分はずっと正しい事をしていたと思っていたけど、そうじゃなかった。自分がしたい事に正しさと言う化粧をしていただけだったんだと。そしてそれは自分を捨てた父親と同じ自分勝手だったんだと。

そして自分を捨てた父親を許せたゴンは、その後で正しい形で父親に会う事が出来た訳です。

はい。

もうこんなの大学で勉強するに値するに決まっています。芸術です。

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

<本文>

1.今週の予定

今週も先週と同じ内容でやっていきます。

  • Niagara: CGHOW氏の何かを勉強する
  • Material :Projectionの勉強の続き
  • Prologueの作成
  • NPCAIを作成する
  • Open Worldの検証や他のMapの作成
  • Game DesignポケモンHxHの念能力( 戦闘システムの作成)
  • UE5naniteの勉強
  • Blenderの勉強

更にBlenderとUEのOpen WorldのTutorialで良さそうなのを見つけたのでそれもやる事にしました。

2.Niagara: CGHOW氏の何かを勉強する

2.1 Eventを使用してNiagara Effectを繋げる方法を勉強する

先週、これのやり方が分からなかったので勉強します。

f:id:kazuhironagai77:20220206214926p:plain

確か一回は勉強した記憶があります。

調べたらありました。

2021-05-17のBlogで勉強していました。

f:id:kazuhironagai77:20220206214953p:plain

取りあえず読み直します。

公式のDocumentであるEvents and Event Handlers Overview [1] を勉強したみたいです。

ちょこっとだけ読んだら結構分かり易くまとめてありました。これ読んだら先週、分からなかった部分も理解出来そうです。

<Event には3つの種類がある>

早速重要な情報が出て来ました。EventにはCollision、Death、そしてLocationの3つ種類があります。

f:id:kazuhironagai77:20220206215021p:plain

先週勉強したHappy New Year ! | Download Free UE4 Niagara Project [2]のNiagara Systemの

f:id:kazuhironagai77:20220206215041p:plain

には、

f:id:kazuhironagai77:20220206215058p:plain

f:id:kazuhironagai77:20220206215119p:plain

が使用されていました。

そもそも先週のEventの使用方法が分からないと言った理由の一つはEventの処理の仕方がそれぞれのEmitterで違うからでした。

Burst Emitterでは以下に示した様にEvent Handler Sectionで前のRockets EmitterのEventを処理しています。

f:id:kazuhironagai77:20220206215145p:plain

所がBurst Emitterで発生したEventはBurst Tails EmitterのEmitter Update SectionのSpawn Particle From Other Emitterで処理しています。

f:id:kazuhironagai77:20220206215207p:plain

この意味がよく分からなかったんです。

しかしそれぞれのEventを見るとBurst EmitterでReceive したEventはDeath EventでBurst Tails EmitterでReceiveしたEventはLocation Eventなんです。

f:id:kazuhironagai77:20220206215228p:plain

そりゃEventの種類が違ったら受け取り方も違うはずです。

ちょっとは理解してきました。

UE4 4.25 Niagara Event Handler Simplest Example [3] を勉強する>

更に2021-05-17のBlogを読み進めたら公式のDocumentであるEvents and Event Handlers Overview [1]は何を言っているのか分からない。のでUE4 4.25 Niagara Event Handler Simplest Example [3] で勉強する事にした。とありました。こんなTutorialで勉強した事、全く覚えていなかったです。

<<Events and Event Handlers Overview [1]のまとめ>

2021-05-17のBlogに書かれているUE4 4.25 Niagara Event Handler Simplest Example [3]について勉強した内容を読む前に2021-05-17のBlogに書かれている公式のDocumentであるEvents and Event Handlers Overview [1]で勉強した内容を以下にまとめておきます。

  • EventにはDeath EventLocation Event、そしてCollision Event3種類がある。
  • Eventを使用するためにはEmitter Settings SectionEmitter Properties ModuleParameterであるRequires Persistent IDsにチェックを入れる必要がある。

f:id:kazuhironagai77:20220206215319p:plain

  • Location Eventを使用するためにはParticle Update SectionからGenerate Location Eventを追加する。
  • すると以下の様なParameterが自動的に生成される

f:id:kazuhironagai77:20220206215350p:plain

  • この後にEvent Handlerを作成して先程作成したLocation EventEventを受け取るんですがそのやり方が分からない。

まあ大体こんな感じの事が書かれていました。

今、公式のDocumentであるEvents and Event Handlers Overview [1]を読み直しましたが、確かにここで指摘されている事

  • Requires Persistent IDsの場所や設定方法
  • Event Handlerの作成方法

についてこのDocumentだけから理解するのは難しいです。

<<UE4 4.25 Niagara Event Handler Simplest Example [3]のまとめ>>

2021-05-17のBlogに書かれているUE4 4.25 Niagara Event Handler Simplest Example [3]について勉強した内容をここにまとめます。どうせもう一回、UE4 4.25 Niagara Event Handler Simplest Example [3]を勉強する事にはなりますが、前回勉強した時には何をここから学んだかを知っておく事は重要です。

うーん。分かり易い。

公式のDocumentであるEvents and Event Handlers Overview [1]で良く分からなかったEvent Handlerの作成方法が綺麗にまとまっていました。

その部分だけここにまとめ直します。

Event Handler SectionにEvent Handler Properties Moduleを追加します。

先週、勉強したHappy New Year ! | Download Free UE4 Niagara Project [2]では以下の部分がそれに当たります。

f:id:kazuhironagai77:20220206215448p:plain

次にEvent Handler Properties Moduleの設定についての解説です。

もう書き直す必要がないくらい綺麗にまとめられているのでそのままScreenshotを貼り付けます。

f:id:kazuhironagai77:20220206215509p:plain

なるほど。

先週、勉強したHappy New Year ! | Download Free UE4 Niagara Project [2]のEvent Handler Properties Moduleも見てみましょう。

f:id:kazuhironagai77:20220206215528p:plain

こっちはRandom Spawn Numberにチェックが入っていますね。そのためMin Spawn Numberも指定する必要があるんですね。

うーん。

先週、何をやっているのか全く理解出来なかったEventの実装方法、かなり分かって来ました。

更に実際にEventを受け取る為には、更にEvent Handler SectionにReceive Death Event Moduleの追加をする必要があるそうです。

f:id:kazuhironagai77:20220206215549p:plain

先週、勉強したHappy New Year ! | Download Free UE4 Niagara Project [2]でもEvent Handler SectionにReceive Death Eventが追加されています。

f:id:kazuhironagai77:20220206215604p:plain

その後にUE4 4.25 Niagara Event Handler Simplest Example [3]ではMinorな問題が発生してEmitter Update SectionのEmitter State ModuleのLife Cycle ModeをSystemに変更したら直ったとあります。

f:id:kazuhironagai77:20220206215626p:plain

先週、勉強したHappy New Year ! | Download Free UE4 Niagara Project [2]ではSelfのままでした。

f:id:kazuhironagai77:20220206215646p:plain

うーん。この部分については良く分かりません。

この後、CollusionとLocation のEventの実装方法もUE4 4.25 Niagara Event Handler Simplest Example [3]では解説されているそうですが、2021-05-17のBlogではやり方が同じだったので記録には残さないと書かれていました。

<<2021-05-17BlogUE4 4.25 Niagara Event Handler Simplest Example [3]を読んで気が付いた事のまとめ>>

Death Eventの実装方法についてはほとんど理解しました。唯一分からない所は、Emitter Update SectionのEmitter State ModuleのLife Cycle ModeをSystemに変更する理由です。

ここまでEventとEvent Handlerについて理解した所、先週、勉強したHappy New Year ! | Download Free UE4 Niagara Project [2]のLocation EventのEvent のHandleの仕方は

f:id:kazuhironagai77:20220206215712p:plain

別にLocation Event特有のやり方じゃなくてどのEventでも出来るやり方の気がしてきました。

要するにEventのReceive方法が2つあってそれぞれ違う結果になるんじゃないのかと思って来ました。

この辺を今度は追及する必要がありますね。

<<UE4 4.25 Niagara Event Handler Simplest Example [3]のLocation Eventの勉強>>

取りあえず、UE4 4.25 Niagara Event Handler Simplest Example [3]のLocation Eventの実装方法を勉強します。ここでSpawn Particle From Other Emitter Moduleを使用していたらそれを勉強すればお終いです。

していなかったです。

Spawn Particle From Other Emitter Moduleを使用してEventを実装する方法は別に勉強する必要がありますね。

Spawn Particle From Other Emitter Moduleを検索したらContent ExampleにSampleがある事が分かりました。

Niagara Advancedにある

f:id:kazuhironagai77:20220206215743p:plain

2.3 Spawn Particles From Another Emitterがそうらしいです。

f:id:kazuhironagai77:20220206215807p:plain

Niagara systemを開いてみると確かにSpawn Particle From Other Emitter Moduleを使用していました。

f:id:kazuhironagai77:20220206215824p:plain

しかしこのサンプル、Eventを発している方のEmitterにはParticle Update Sectionで

f:id:kazuhironagai77:20220206215842p:plain

以下の様なEvent Moduleを使用していません。

f:id:kazuhironagai77:20220206215906p:plain

むむむ。です。

こっから詰まってしまって何処にも参考に出来る資料が見つからなくなってしまったんですが、日本語で詳しく解説しているサイトがありました。

【UE4.26】Niagara Advanced 解説基礎編~Particle Attribute Reader~ [4] です。

このサイトの記事を読んだら以下の事が判明しました。

  • Spawn Particle From Other Emitter Moduleを使用してEffectからEffectに情報を伝達するやり方はEvent とは全く別な方法でEmitter同士をやりとりするParticle Attribute Readerと言う技術でした。
  • この方法だとGPUで生成したParticleの情報でもEmitter同士でパス出来る。
  • 先程のContent Exampleで見た3 Spawn Particles From Another Emitter2.12.2Particle Attribute Readerの使用例である。

その後でこのサイトではContent Exampleの2.1、2.2、そして2.3の詳しい解説をしています。

うーん。凄い分かり易い。

Particle Attribute Readerで検索したらCGHOW氏のTutorialが何個か表示されました。

f:id:kazuhironagai77:20220206215935p:plain

うん。これは結構、勉強する必要がありそうです。Particle Attribute Readerは来週勉強する事にします。

2.2 UE4 4.25 Niagara Event Handler Simplest Example [3]の実装

Particle Attribute Readerは来週勉強する事にして、今週はUE4 4.25 Niagara Event Handler Simplest Example [3]をもう一回勉強してEventの使い方を完全に理解する事にします。

まずNiagara EmitterからFountain Templateを選択して以下の様なEmitterを作成します。

f:id:kazuhironagai77:20220206220002p:plain

これはEventを発するためのEmitterでしょうね。

こんなのNiagara Systemを一個作成してその中で2つのEmitterを作成すれば良いじゃん。と思いますが、人によってやり方はそれぞれなんでしょうね。この人はこうやって一個ずつ作成していくのが好きなんでしょうね。

Event をReceive する側のEffectはOmnidirectional Burstから作成するそうです。

f:id:kazuhironagai77:20220206220020p:plain

因みに、Omni-ってAllという意味だそうです。この場合は全方位って意味になるんでしょうね。

NEを開いて見たら、やっぱし一点から全方位に速度が加えられていました。

f:id:kazuhironagai77:20220206220038p:plain

更にNiagara Systemを作成して今作成した二つのEmitterを追加します。

f:id:kazuhironagai77:20220206220107p:plain

はい。出来ました。

Particle Update SectionにGenerate Death Event Moduleを追加します。

f:id:kazuhironagai77:20220206220122p:plain

Emitter Setting SectionのEmitter Properties Moduleの

f:id:kazuhironagai77:20220206220141p:plain

にチェックを入れます。

2021-05-17のBlogを見るとGenerate Death Event ModuleのGap Correction Amountの値が

f:id:kazuhironagai77:20220206220203p:plain

これについて少しだけ調べます。

f:id:kazuhironagai77:20220206220223p:plain

と書かれていました。

うーん。0でも大丈夫そう。取りあえず今回は0にしておきます。

これでEvent 側の設定は終わりです。今度はEvent Handler側の設定をします。

NE_OminDirectional のEvent Handler SectionにEvent Handler Properties Moduleを追加します。

f:id:kazuhironagai77:20220206220240p:plain

SourceにEmitter: NE_Fountain, Event: Death Eventをセットします。

f:id:kazuhironagai77:20220206220301p:plain

更にExecution ModeにSpawned Particleをセットします。

Spawn Numberは5をセットします。

これらのParameterについて調べます。

Sourceは明らかにEventの場所を指定しているのでこれは調べません。次のExecution Modeを調べます。

Execution Modeです。

f:id:kazuhironagai77:20220206220320p:plain

どのParticleでEvent Scriptが走るのかを決めるとあります。Spawned ParticleとEvery Particleがあります。Every ParticleだとUpdateするたびにEventが発生するんでしょうか?

Spawn Numberです。

f:id:kazuhironagai77:20220206220339p:plain

Eventに対して発生するParticleの数を指定している箇所でしょうね。

次に行きます。

今度はEvent Handler SectionにReceive Death Event Moduleを追加します。

f:id:kazuhironagai77:20220206220356p:plain

更にEmitter Update SectionのLife Cycle ModeをSystemに変更します。

f:id:kazuhironagai77:20220206220418p:plain

これが前回やった時、どうしてこれをする必要があるのかが分からなかったヤツです。

少しだけ調べる事にします。

f:id:kazuhironagai77:20220206220439p:plain

うーん。

別に知らない事はないですね。

この辺も自分で試しながらチェックするしかないですね。

一応これで前のEmitterのSpriteが死んだときに新しいSpriteが発生するNSが完成しました。

f:id:kazuhironagai77:20220206220454p:plain

はい。

大体理解しました。

今度は全部自分で作成してみます。

f:id:kazuhironagai77:20220206220723g:plain

基本的な部分は同じですがEventの方のParticleの数を極限まで減らしてEventのEmitterとEvent HandlerのEmitterの関係がはっきりするようにしました。

上のGifを見るとEventのParticleが死んでからEvent HandlerのEmitterが開始していていますが、そのためには、上記の設定以外にも以下に示したEmitter Update SectionのEmitter State ModuleのLoop Durationの値をEventとEvent Handlerの両方で同じ値にする必要がありました。

f:id:kazuhironagai77:20220206220746p:plain

後、Event Handler Section のEvent Handler PropertiesのExecution ModeもEvery Particleにセットする必要がありました。

f:id:kazuhironagai77:20220206220807p:plain

f:id:kazuhironagai77:20220206220813p:plain

この辺も謎ですね。

うーん。

この後にLocation EventやCollusion Eventも試そうと思っていたんですが、もう少しEvent 自体を弄って機能を理解する必要がありますね。

今週はここまでにして来週また検証する事にします。

3.Material: Projectionの勉強の続き

今週もBen Cloward先生のProjection SeriesのTutorialを勉強していきます。

今週はTriplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [5]を勉強します。

これがProjection Seriesの最後のTutorialのようです。今週でこのTutorialの勉強が終わった場合、来週からはこのProjection Seriesのまとめをやります。兎に角このProjection Seriesは凄いです。このProjection Seriesの勉強を通じてMaterialへの理解が2、3割は増しました。

3.1 Triplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [5] を軽く見る

今週も先週までと同じ様に最初にTutorialを全部見てどんな内容を教えているのかを簡単に把握する事にします。

後、Tutorialの動画を見る前に先週のBlogのMaterialの部分を読み直して、先週やり残した部分で検証が必要なところは無い事を確認しました。

それでは見てみます。

一回だけ軽く見ましたが、今回のTutorialは難しすぎるかもしれません。正直、良く理解出来ない箇所が沢山あって全体の流れすら部分的にしか負えませんでした。

一応、理解した範囲でまとめます。

  • 今回のTutorialの目的は、Normal MapProjectionです。
  • 前回作成したTri-planar Projection Textureの部分にNormal Mapを使用します。このやり方だと間違ったNormal Mapが生成されます。
  • それはNormal MapProjectしないで普通に貼り付けた球のMeshで比較すると間違っている部分が可視化され簡単に指摘出来ます。
  • そしてその間違いが起きた部分を一つ一つ直して行っています。

これが一応、私が理解した内容です。

しかしその一個一個の間違いの内容になると、全然理解出来ません。

うーん。

もう一回見る事にします。全体の流れを理解出来ないと細かい部分だけしっかり勉強しても最終的な理解に繋がらないですから。

3.2 もう一回、Triplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [5] を見る

今度は見ながらまとめていく事にします。

2つの球をLevel上に配置しました。

f:id:kazuhironagai77:20220206220916p:plain

上の球に使用されているMaterialは普通にNormal Mapを使用しています。

f:id:kazuhironagai77:20220206220940p:plain

つまりこれが正しいNormal Mapの配置になります。

Normal MapをProjectionした場合も、このMaterialの配置と同じになる必要があります。

下の球に使用しているMaterialです。

f:id:kazuhironagai77:20220206220959p:plain

これは先週、作成したTri-planarのProjectionのMaterialのTexture SampleをNormalのそれに代えて計算結果をResult MapのNormal に繋いだMaterialです。

今度はNormal MapがどのようにこれらのMeshに貼りつけられているのかを可視化するためにView Port 1のView ModeをWorld Normalにセットします。

f:id:kazuhironagai77:20220206221023p:plain

この辺の機能は全然知りません。

更にWorld Normalの意味もあんまり良く分かっていません。World 座標におけるNormalって事なんでしょうか?

以下のような表示になりました。

f:id:kazuhironagai77:20220206221045p:plain

ここから正しいNormal MapとTri-PlanarでProjectionした場合のNormal Mapの比較が始まります。

<後面の上部>

後ろから見た場合の球の上面です。

正しいNormal Mapです。

f:id:kazuhironagai77:20220206221112p:plain

Tri-PlanarでProjectionした場合のNormal Mapです。

f:id:kazuhironagai77:20220206221127p:plain

Tutorialの解説によると正しいNormal Mapでは青い部分がブツブツの上側に出ていますが、Tri-PlanarでProjectionした場合のNormal Mapではブツブツの下に出ています。

正直に言って私の目では分からないです。

それよりも、Tri-PlanarでProjectionした場合のNormal Mapではぶつぶつが凹んで見えます。

そしたらTutorialで「ここではNormal Map をTri-PlanarでProjectionした場合、間違っている事が視覚的に理解出来れば良い。」って言ってました。

はい。先へ進みます。

<何故、Normal Mapだと間違った結果になるのか?>

ここから、何でNormal MapをTri-PlanarでProjectionした場合、間違った結果になるのかについての説明になります。

この部分が最初に聞いた時、全く理解出来ませんでした。

今度はゆっくりちょっとずつ聞く事にします。

まずNormal MapはTangent Spaceに展開されると予測されて作成されています。つまりそれはMeshのUV Coordinate上に展開されると言う意味です。ところが、先週作成したTri PlanerでNormal MapをProjectした場合、UV Space上(原文ママ)にNormal Mapを展開しています。

UV Space上(原文ママ)と言うのはWorld Spaceの単なる言い間違いかもしれません。

でも言いたい事は分かりました。Coordinateが間違っている訳です。

先週作成したTri-planarでNormal MapをProjectionした場合、Normal Mapを使用出来るCoordinateではない所でNormal Mapを使用しています。その結果間違ったNormal MapがProjectされる結果になったと言う訳です。

細かい点の理解は間違っているかもしれませんが、大意は掴みました。

今度はこのTutorialの流れを理解出来そうですね。

<Build-in Nodeについて>

ここは全体の流れとは関係ないのでSkepします。

が超大切なお話がBen Cloward先生からここであったのでそれを記録に残すために簡単に流れだけまとめておきます。

先週、勉強したTri Planarを使用したProjectionを公開した後で、一部の視聴者から以下のNodeを使用すれば

f:id:kazuhironagai77:20220206221159p:plain

f:id:kazuhironagai77:20220206221207p:plain

一々、Tri Planarを使用したProjectionを実装しなくても全部やってくれるから無駄です。と

それに対するBen Cloward先生から回答です。

Because of that It's Important to understand the underlying workings of these nodes so if they’re not doing what you want you can do something else to make them better.

これらのNodeの中身がどうやって計算しているのかを理解する事で、これらのノードが自分が望んだ結果を返さない場合にどうやって改良したら望んだ結果を得られるのかが分かるようになる。(だから一つ一つの計算方法とその理論を理解するのは大切だと。)

全く同感です。

Game制作の観点から言えば、既に作成されているMaterialをどうやって適応させるかを考えるだけで99%の場合で十分でしょう。でも私はそれがどうやって計算されているのかまで知りたいんです。それは残り1%の事態が起きた時でも対応できるようにしておきたいからです。

Ben Cloward先生のこの回答はあまりにも美しく目頭が熱くなってしまいました。

<World SpaceからTangent Spaceへ>

以下のNormal Mapにパスされる値は

f:id:kazuhironagai77:20220206221258p:plain

Tangent Spaceの値であると仮定されています。

しかしTri-planarでNormal MapをProjectionした場合はWorld Spaceの値で計算されています。

Transform ノードを使用してWorld Spaceの値をTangent Spaceに変換します。

f:id:kazuhironagai77:20220206221315p:plain

以下の様な結果になります。

f:id:kazuhironagai77:20220206221333p:plain

まるで正しいNormal Mapを上から見てる時の様です。(以下に正しいNormal MapのTop viewを示します。)

f:id:kazuhironagai77:20220206221351p:plain

うん。確かにそっくりです。

これはz軸のProjectionは正しいですが、x軸とy軸のProjectionは間違っているって事です。

これを直します。

<Projectionの直し>

x軸とy軸のProjectionの直しは以下の部分にコードを追加して直します。

f:id:kazuhironagai77:20220206221414p:plain

直すためには2つの事をする必要があります。

まずこのNormal MapとVertex Normal Mapの値を合わせます。そしてそれぞれのChannelの配置を変更します。

うう。

ここで分からなくなりました。

x軸とy軸でも正しいNormal MapがProjectされるようにするためには、それぞれのChannelの配置を変えるのは何となく理解出来ます。

でもNormal MapとVertex Normal Mapの値を合わせるのは何故なんでしょうか?ここが分かりません。

あ。分かりました。

その後で、Z軸のProjectionでもNormal MapとVertex Normal Mapの値を合わせる実装をしています。

f:id:kazuhironagai77:20220206221435p:plain

Z軸のProjectionは正しいので軸は直す必要はないはずです。これは多分ですが、Texture Sampleの値を正しいWorld Spaceの値に変更するための計算だと思います。

<Z軸方面のProjectionの直し>

Z軸のProjectionに対してVertex Normal WSのx,yの値は足し、zの値は掛けています。

f:id:kazuhironagai77:20220206221458p:plain

この辺の理由は全く分かりません。

更に、底面の赤の値が逆になっています。

f:id:kazuhironagai77:20220206221521p:plain

以下の方法で直します。

f:id:kazuhironagai77:20220206221537p:plain

これも何でこの方法で直るのか分かりません。後で検証します。

<Y軸方面のProjectionの直し>

今度はY軸方面を直します。

Normal MapとVertex Normal Mapの値を合わせ方ですが、Y軸ではAdd, Multiply, Addになります。

f:id:kazuhironagai77:20220206221600p:plain

軸は掛け算、それ以外は足し算だそうです。

ここで、Z軸のProjectionにはない「それぞれのChannelの配置を変更。」を行います。

f:id:kazuhironagai77:20220206221617p:plain

Texture SampleのGの値をBに、Bの値をGにパスします。

ここまでの結果を見ます。

f:id:kazuhironagai77:20220206221632p:plain

正しいNormal Mapの結果です。

f:id:kazuhironagai77:20220206221646p:plain

正しいNormal Mapの場合青がブツブツの上側にあります。Tri Planarの結果は青が下側にあります。

直します。

まずGreenの値に-1を変えてFlipします。

f:id:kazuhironagai77:20220206221706p:plain

うーん。これをやる理由は分かりません。

次にRの値にVertex Normal WSのGの値を掛けます。

f:id:kazuhironagai77:20220206221726p:plain

これも何をやっているのかは不明です。

Tutorialではこれをやる理由はRを裏返しにするためだ。と言っています。後で検証します。

Tri Planarの結果です。

f:id:kazuhironagai77:20220206221747p:plain

正しいNormal Mapの結果と同じように青と赤がブツブツの上側に移動しました。

<x軸方面のProjectionの直し>

Normal MapとVertex Normal Mapの値を合わせ方ですが、x軸ではMultiply, Add ,Addになります。

f:id:kazuhironagai77:20220206221812p:plain

「それぞれのChannelの配置を変更。」ではBがR、RがG、そしてGがBになります。

f:id:kazuhironagai77:20220206221831p:plain

何でこうなるのかは分かりませんが、何か一点理解したら全部理解出来そうです。後でこの部分も検証する事にします。

Vertex Normal Mapのそれぞれの値を繋いで結果を見ます。

結果です。

f:id:kazuhironagai77:20220206221852p:plain

正しいNormal Mapです。

f:id:kazuhironagai77:20220206221909p:plain

正しいNormal Mapではブツブツの下側が黄色くなっていますが、Tri-planarの場合はブツブツの上側が黄色くなっています。

これを直します。

まず、Gに-1を掛けて値を逆にします。

f:id:kazuhironagai77:20220206221926p:plain

RにはVertex Normal WSのSignのRを掛けて裏面だけ逆にします。

f:id:kazuhironagai77:20220206221944p:plain

ああ、そういう意味だったんですね。良く考えればSignノードを使用しているんだから裏面だけ逆にする時にこれを掛けていたわけです。納得しました。

改良した結果です。

f:id:kazuhironagai77:20220206222003p:plain

正しいNormal Mapと同じ様にブツブツの下側が黄色くなっています。

<結果とまとめと感想>

それぞれの結果を以下の実装でまとめました。

f:id:kazuhironagai77:20220206222037p:plain

結果です。

f:id:kazuhironagai77:20220206222056p:plain

正しいNormal Mapです。

f:id:kazuhironagai77:20220206222113p:plain

細かい部分の計算でなぜそれが必要なのか分からない所はそれなりにありましたが、全体の流れは理解しました。

3.3 Triplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [5] を実装する

完全に流れは理解したので自分でも実装してみます。

左側が普通のNormal Mapを使用したMaterialで、右側が先週作成したTri-planar ProjectionのTexture SampleにNormal Textureを入れただけのMaterialです。

f:id:kazuhironagai77:20220206222136p:plain

左側の球に使用したMaterialの実装です。

f:id:kazuhironagai77:20220206222153p:plain

左側の球に使用しているMaterialがProjectionである事を示しました。

f:id:kazuhironagai77:20220206222216g:plain

これだけ見るとX軸が正しくてZ軸が逆になっているように見えますね。

f:id:kazuhironagai77:20220206222253p:plain

f:id:kazuhironagai77:20220206222308p:plain

View ModeをWorld Normalに変更しました。

f:id:kazuhironagai77:20220206222326p:plain

このWorld Normalの値が何を示しているのかが理解していないのでそれから調べます。

普通のNormal Mapを使用したMaterialをほぼ原点にセットします。

f:id:kazuhironagai77:20220206222350p:plain

f:id:kazuhironagai77:20220206222402p:plain

X軸に沿って移動させました。

f:id:kazuhironagai77:20220206222421p:plain

f:id:kazuhironagai77:20220206222431p:plain

軸の移動では色の変化はみられません。

今度は回転させます。

X軸方向に90度回転させました。

f:id:kazuhironagai77:20220206222454p:plain

f:id:kazuhironagai77:20220206222504p:plain

模様の変化から球が回転したのが確認出来ますが、色は変化していません。

これがWorld CoordinateにおけるNormal Mapと言う意味なんでしょうか?

Normal Mapの色が位置によって変化しないは確認出来たので、今回の検証に使用する分には問題ないでしょう。続きをやる事にします。

Transform ノードを使用してNormal Mapの計算結果をWorld SpaceからTangent Spaceに変換します。

f:id:kazuhironagai77:20220206222522p:plain

f:id:kazuhironagai77:20220206222530p:plain

あれ。

感じが随分変わってしまいました。

f:id:kazuhironagai77:20220206222551p:plain

Tutorialを見たら普通のNormal Mapを使用したMaterialを上から見た図とそっくりになっている。と言っていました。

f:id:kazuhironagai77:20220206222612p:plain

確かに色合いがそっくりです。

これがZ軸へのProjectionは正しい理由に繋がる訳ですね。

x軸とy軸のProjectionの直しやNormal MapをTangent SpaceからWorld Spaceに変換するための計算に使用しる実装部を先に作成しました。

f:id:kazuhironagai77:20220206222642p:plain

以下の部分は

f:id:kazuhironagai77:20220206222701p:plain

先週作成したTr-Planerの向きを直すための実装の以下の部分と同じでした。

f:id:kazuhironagai77:20220206222721p:plain

この辺はまた後で検証する事にします。

Z軸方面のProjectionのTangent SpaceからWorld Spaceへの変換を行いました。

f:id:kazuhironagai77:20220206222735p:plain

この後で更に、底面のRの値をFlipする必要があります。

その前に本当に底面の赤が逆になっているのが確認できるか見てみます。

Tri-planar Normalの底面です。

f:id:kazuhironagai77:20220206222752p:plain

正しいNormalの底面です。

f:id:kazuhironagai77:20220206222809p:plain

うーん。

確かにTri-planar Normalの底面は赤が右上よりですが、正しいNormalの底面は赤が左上よりに見えます。

でもそれを言うと緑色も反対の様に見えます。

正直良く分かりません。

底面の赤をFlipするために以下の実装を追加しました。

f:id:kazuhironagai77:20220206222828p:plain

赤が左上に変化しました。

f:id:kazuhironagai77:20220206222846p:plain

うーん。成程。ついでに緑色も反対に移動しています。バックの色が黄色と言う事は赤色が抜けると自然に緑色になる訳でした。

今度はY軸にProjectした場合です。

まずはここまで組みました。

f:id:kazuhironagai77:20220206222903p:plain

何故このように組むのかについては全く分かっていません。

結果です。

f:id:kazuhironagai77:20220206222921p:plain

正常なNormal の場合です。

f:id:kazuhironagai77:20220206222942p:plain

青が逆ですかね。

Tutorialでも青色が逆になっていると言っていました。

これを直すために以下の実装を追加しました。

f:id:kazuhironagai77:20220206223002p:plain

青色なるGの値に-1を掛けます。

次に赤色にVertex Normal WSのSignのGを掛けます。

一寸だけ理解出来た部分を書いて置くと青は正面と裏面の両方が逆なため-1を掛けています。赤は裏面だけが逆なのでSignの値を掛けているはずです。

はい。

結果です。

f:id:kazuhironagai77:20220206223021p:plain

青が上になりました。

最後にx軸方面にProjectした場合の直しをします。

まずは以下の部分だけ作成しました。

f:id:kazuhironagai77:20220206223037p:plain

今度はTexture SampleのBをRにRをGにGをBに接続しました。

結果です。

f:id:kazuhironagai77:20220206223053p:plain

正しいNormal Mapの場合です。

f:id:kazuhironagai77:20220206223110p:plain

赤と青が逆でしょうか。緑も逆ですがこれは赤が逆な結果かもしれません。

裏面も見ておきます。

f:id:kazuhironagai77:20220206223126p:plain

正しいNormal Mapの場合です。

f:id:kazuhironagai77:20220206223147p:plain

赤の位置は合っていますね。黄色が反対ですね。黄色が反対と言う事は緑が反対なんでしょうか?

正直青は分からないです。合ってるように見えます。

これらを直すために以下の実装をしました。

f:id:kazuhironagai77:20220206223206p:plain

青を全部逆にしています。

さらに緑を裏面だけ逆にしています。

全然、予測と違う。

兎に角、結果を見てみます。

f:id:kazuhironagai77:20220206223223p:plain

緑が左下になって正しいNormal Mapと同じになりました。

裏面です。

f:id:kazuhironagai77:20220206223239p:plain

赤が左側になり正しいNormal Mapと同じになりました。

うーん。何で?

最後にそれぞれの結果をLerpで繋げました。

f:id:kazuhironagai77:20220206223318p:plain

結果です。

f:id:kazuhironagai77:20220206223335p:plain

f:id:kazuhironagai77:20220206223347p:plain

f:id:kazuhironagai77:20220206223359p:plain

f:id:kazuhironagai77:20220206223410p:plain

ほぼ正しいNormal Mapと同じ結果になっていますね。

Litで見ても陰の付き方が一定になっています。

f:id:kazuhironagai77:20220206223434p:plain

ただし近づくとTri-Planarのつなぎ目が目立ちます。

f:id:kazuhironagai77:20220206223457p:plain

これはTextureのつなぎ目の無い奴でやったらどうなるんでしょうか。消えるかもしれませんね。

Blendの値を弄ってみました。それなりにはつなぎ目も消せますね。

f:id:kazuhironagai77:20220206223514p:plain

3.4 Triplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [5]のまとめと感想

一応、最後まで出来ました。途中の計算が何をやっているのかは一寸分からないです。来週、計算の理屈を考えてみますが、ちょっと難しいかもしれません。

それでもかなり色々な事が勉強出来ました。

来週は、今日実装した内容で理解出来ない部分を検証、考察します。再来週以降はProjectionのTutorialのまとめを行います。

4.Prologueの作成

4.1 忘れていたThemeを追加する

2022-01-10のblogでは考えていたんですが、その後のStoryの改変ですっかり忘れてしまった要素がありました。

それは選択です。

Playerは常に色々な選択を迫られます。その選択によって金の切符が得られるのかどうかが決まって来ます。どの選択が正しいのか、常に問われていくわけです。

もうこれは私が作成するRPGなんで、選択は100個ぐらい作成してその中で唯一の正解にたどり着けた場合のみ金の切符が手に入るようにします。

所で先週作成したPrologueですが、Prologueの時点で主人公の少年、何個かの重大な選択を既にしていました。

まずこのシーンです。

f:id:kazuhironagai77:20220206223600p:plain

銀河鉄道の結末に怒っています。主人公は本の結末に激怒する選択をしています。

更に神社で神様にカムパネルラを生き返らせてくださいとお願いする選択もしました。

f:id:kazuhironagai77:20220206223622p:plain

次に夢のお告げに従って、夜中におばあちゃんの家を抜け出して神社まで行っています。

夜中に家を抜け出すと言う重大な選択をしました。

f:id:kazuhironagai77:20220206223637p:plain

最後に、カムパネルラを生き返らせるために銀河鉄道に乗って幻想界に行って金の切符を手に入れる決断をします。

これってどうなんでしょう。

うーん。Prologueなんで主人公が決断する時にPlayerが決定権がなくても良い気はします。

正直、これ以上綺麗な話を作れる気はしません。

4.2 推敲する

文を推敲しようと思ったんですがどう直すべきなのかの方向性が分かりません。うーん。困った。

文の推敲はちょっと置いておいて簡単に直せる箇所を直す事にしました。

それは吹き出しの枠の作成と人物の絵の書き換えです。

吹き出しの枠を作成しました。

f:id:kazuhironagai77:20220206223657p:plain

こんな感じです。

f:id:kazuhironagai77:20220206223714p:plain

主人公の少年です。

f:id:kazuhironagai77:20220206223731p:plain

お婆ちゃんです。

f:id:kazuhironagai77:20220206223748p:plain

お化けの女の子です。

f:id:kazuhironagai77:20220206223805p:plain

一つ目小僧です。

f:id:kazuhironagai77:20220206223825p:plain

狐です。

f:id:kazuhironagai77:20220206223847p:plain

火の玉です。

f:id:kazuhironagai77:20220206223911p:plain

残りは来週作成します。

5.NPCAIを作成する

Prologueが完成しないとNPCのセリフが決まりません。のでNPCのAIの作成は一端、完成とします。最初の目的であるNPCをAIで歩かせるはとっくに達成していますし。

6.Open Worldの検証や他のMapの作成

6.1 Open Worldの検証

UE4のWorld CompositionやUE5のWorld Partitionを勉強してUEでMapを作成する場合は、何個ものMapを作成するより巨大なOpen Worldを一個作成した方が効率が良い気がして来ました。

ただし、Open Worldを作成する場合、

  • Mapの大きさはどれくらいが適当なのか、
  • LandscapePaintのやり方とかFoliageのやり方などは小さいMapの作成と同じで良いのか、
  • World Compositionを採用する場合はSub Levelの大きさはどれぐらいが適当なのか

この辺の調査をする必要があります。

そのためにSmart Poly氏のHow To Make A Massive Open World Map In Unreal Engine 4 [6] とUnreal Engine 5 | Open World Tutorial Using World Partition [7] を勉強する事にしました。

Smart Poly氏のTutorialを勉強するのは始めてですが、UEの最新の機能の紹介とその使い方の詳しい解説をしていて、キレッキレな動画を作成している事は知っています。

ただ声が非常に小さいんで正直何を言っているのか分からない時があります。

まあ、取りあえずやってみますか。

6.2 Smart Poly氏のHow To Make A Massive Open World Map In Unreal Engine 4 [6]を軽く見る

Tutorialを先に一回軽く見ておくと、そのTutorialの最適な勉強方法が分かります。のでこのTutorialも一回軽く見る事にします。

まずWorld Machineと言うソフトの有料版でLandscapeを作成しています。

このサイトですね。

f:id:kazuhironagai77:20220206224016p:plain

商業利用じゃない場合は無料のようです。

f:id:kazuhironagai77:20220206224033p:plain

有料版でもそんなに高くないですね。

f:id:kazuhironagai77:20220206224051p:plain

そう言えばUnreal SenseiのTutorialでもUEで使用するLandscapeはUEで作るべきじゃない。といって専門のSoftを紹介していました。

このWorld MachineはそれらのSoftと比較した場合、どんな長所があるんでしょう。

2021-03-28のBlogUnreal SenseiのTutorialで紹介されているLandscape作成用のソフトについてまとめられていました。

f:id:kazuhironagai77:20220206224108p:plain

あれ、これもWorld Machineでした。

更にそのBlog内に

f:id:kazuhironagai77:20220206224124p:plain

と書かれていました。

うーん。どうやらUEでGameなどを制作する人達にとってWorld Machineを使用してLandscapeを作成するのは常識のようですね。

今回のこのTutorialはWorld Machineで作成したDataは提供してくれるそうなのでそれを使用します。

一応、確認しておきます。

DownloadしたOpenWorldMap.rarを解凍しようとしたら

f:id:kazuhironagai77:20220206224139p:plain

こんなErrorが。

色々調べたら最新のVersionの.rarをLhaplusで解凍するとこうなるらしいです。7-Zipで解凍したら出来ました。

f:id:kazuhironagai77:20220206224159p:plain

結構焦りました。解凍出来ないならそう言ってほしかったです。

それではTutorialを見ます。

最初はWorld Machineの使用方法です。

ここで作成しているLandscapeのサンプルですがサイズが

f:id:kazuhironagai77:20220206224220p:plain

でした。

こんなデカイLevelを作成出来るの。

これは楽しみです。

World MachineのTutorialの部分を見終わりました。

思っていたより簡単に動かせそうです。後で無料版で勉強してみますか。

UE4のTutorialですが、まず海を作成するのに

f:id:kazuhironagai77:20220206224242p:plain

を使用しています。別に使用しなくても良いそうですが、ここはTutorialに従ってやる事にします。

後は特に記録する事はなかったです。やってみれば分かる気がします。

6.3 Smart Poly氏のHow To Make A Massive Open World Map In Unreal Engine 4 [6]をやってみる

それでは実際にOpen Worldを作成してみます。

まずはUE4-Occean ProjectをDownloadします。

f:id:kazuhironagai77:20220206224305p:plain

解凍したら普通に.uprojectがあるので開いて見ます。

f:id:kazuhironagai77:20220206224335p:plain

f:id:kazuhironagai77:20220206224344p:plain

真っ暗ですね。

Environment Mapを開いても真っ黒です。

f:id:kazuhironagai77:20220206224400p:plain

これはSky Sphereとかを自分で追加する必要があるの?

f:id:kazuhironagai77:20220206224427p:plain

うーん。

よくよく考えたら海を今すぐ作成する必要なさそうです。

海なしで作成します。

普通のLevelを別に作成しました。

f:id:kazuhironagai77:20220206224447p:plain

次にMaterialを作成します。

f:id:kazuhironagai77:20220206224505p:plain

Landscape Layer Blendノードを追加します。

f:id:kazuhironagai77:20220206224522p:plain

以下の4つのLayerを追加します。

f:id:kazuhironagai77:20220206224540p:plain

Rockだけは

f:id:kazuhironagai77:20220206224559p:plain

で残りは

f:id:kazuhironagai77:20220206224616p:plain

です。

Landscape Layer Blend ノードは前にLandscapeを作成した時に使用したかもしれませんが覚えていません。

もう一回勉強し直します。

以下の様にResult ノードの要素に値を繋げます。

f:id:kazuhironagai77:20220206224637p:plain

TutorialではSpecularも0で指定しているんですが、良く分からん。取りあえずは開けておきます。

以下の様になりました。

f:id:kazuhironagai77:20220206224658p:plain

これは流石に初めて使用するNodeだと思います。Landscape Coordノードです。

f:id:kazuhironagai77:20220206224717p:plain

公式のDocumentであるLandscape Expressions [8] に以下の解説がありました。

f:id:kazuhironagai77:20220206224734p:plain

Landscape用のTexCoord[0]だと思って良さそうですね。

後で詳しく検証します。

Rock用のLandscape CoordのMapping Scaleを100にセットします。Grassは300、Sandは200にセットします。

f:id:kazuhironagai77:20220206224840p:plain

これでLandscape用のMaterialの設定は完了のようですね。

Levelに戻ってEnable World Compositionにチェックを入れます。

f:id:kazuhironagai77:20220206224902p:plain

そしてLevelsのImport Tiled Landscape…から先程downloadしたFileに入っているLandscapeのheight mapをImportします。

f:id:kazuhironagai77:20220206224921p:plain

以下のWindowが表示されるのでSelect Heightmap Tiles…をクリックして

f:id:kazuhironagai77:20220206224939p:plain

Tutorialで指定されているFileを選択しました。

次にMaterialに先程作成したMaterialをセットします。

f:id:kazuhironagai77:20220206224955p:plain

すると以下の表示が現れるので

f:id:kazuhironagai77:20220206225012p:plain

それぞれのSelect Weightmap Tiles…をクリックしてTutorialで指定されたfileを読み込みました。

f:id:kazuhironagai77:20220206225037p:plain

最後にLandscape ScaleのZの値を70.0にします。

f:id:kazuhironagai77:20220206225056p:plain

この辺の値が駄目だった時は単にもう一回Importして作り直せば良いそうです。

f:id:kazuhironagai77:20220206225113p:plain

Y CoordinateをFlipしたままですね。

f:id:kazuhironagai77:20220206225132p:plain

World Machineで生成されるMapもY軸が逆なんでしょうか?

以下の表示が、

f:id:kazuhironagai77:20220206225154p:plain

ひょっとすると読み込んではいけないfileもImportしちゃたんかもしれません。

一応、読み込めました。

f:id:kazuhironagai77:20220206225212p:plain

Loadしました。

f:id:kazuhironagai77:20220206225233p:plain

Landscapeの位置を真ん中に移動しました。

f:id:kazuhironagai77:20220206225254p:plain

あれ。3.70kmになっています。56kmじゃないの?

何か以下の黄色の枠内でしがGameは出来ないみたいな話をしています。

f:id:kazuhironagai77:20220206225312p:plain

この枠から出る為には以下のEnable World Bound ChecksのCheckを外す必要があるそうです。

f:id:kazuhironagai77:20220206225604p:plain

これも後でどんな機能なのか調べます。

後、kill Zの機能の解説で

f:id:kazuhironagai77:20220206225628p:plain

Playerがある範囲を超えて移動した場合にPlayerを殺す機能と説明していますが、これって落下し過ぎた時にPlayerを殺す機能だった気もします。

これも後で調べます。

もしstreamingのサイズを変更したい場合は以下の設定で設定します。

f:id:kazuhironagai77:20220206225700p:plain

これは覚えています。Tutorialでは200,000に設定していたので同じにします。

大体これで終りでした。

こんな感じです。

f:id:kazuhironagai77:20220206225719p:plain

うーん。

あんまり知らない事はなかったですね。

後、何で56kmが2.52kmになっているでしょうか。50km位のサイズのOpen Worldが簡単に作成出来ると思ってたんですがそうじゃなかったみたいです。

6.4 Open Mapのまとめと考察

How To Make A Massive Open World Map In Unreal Engine 4 [6]を勉強したら50km位の巨大なOpen World を生成する方法が学習出来ると思って勉強してましたがどうやら違ったみたいです。でもヒントは得る事が出来ました。

まず巨大なOpen Worldを作成するためにはWorld Machineと言うソフトの使い方を覚える必要があります。

これはほとんど全てのLandscapeのTutorialでHeight Mapの作成にWorld Machineを使用している事から間違いないでしょう。

World Machineの使用方法を覚えたらUE4内で50km^2のサイズになるMapを作成してみます。そしてそれを今回のTutorialのやり方でLandscapeとして作成してみます。恐らくですがSmart Poly氏のようなキレッキレの動画を作る人が紹介したやり方ですので、もっとLandscapeのサイズを大きくても今回のTutorialのやり方で出来るはずです。

後はEnable World Bound Checks関連の勉強ですね。黄色の枠からPlayerが飛び出しても死なないような設定に変更しないといけないみたいですので。

前に勉強したLandscapeの作成方法やWorld Compositionの復習をする必要もあります。前に勉強したLandscapeの作成やWorld Compositionの指定方法など全然覚えていませんでした。

最初の以下の質問は、今まで勉強したLandscapeの作成方法とWorld Compositionの作成方法からも検討します。

f:id:kazuhironagai77:20220206225750p:plain

正直、DownloadしたOpenWorldMap.rarが解凍出来ない事で焦ってしまい、その後の集中力が切れてしまいました。

そのせいで、海の生成なんかは今回の目的に全然関係ないんだから一回動画を見た時点でスキップする決定が出来たはずですが、そういう所に気が回らなくなって結構グダグダしてしまいました。

6.5 Open Mapを作成したい!

それぞれの舞台のLevelの大きさは4km^2位が丁度良い気がしますが、物語の終盤では空を飛んで、今までに行った全ての場所を空からアクセス出来るようにしたいんです。

そうするとやっぱりOpen Worldを作成した方が良いに決まっています。

UE4 Open Worldで検索したら以下の公式のDocumentであるOpen World Tools [9]が見つかりました。

f:id:kazuhironagai77:20220206225826p:plain

こっちも読む事にします。

f:id:kazuhironagai77:20220206225853p:plain

6.6 来週以降の計画

以下の3つの事をこれからやっていこうと思います。

今回の勉強で得られた知見を元にすると上2つがこれからの勉強の対象になりますが、一応今週やる予定であったSmart Poly氏のUnreal Engine 5 | Open World Tutorial Using World Partition [7]も勉強しておこうとは思います。

UE5に移った時に浦島太郎みたくはなりたくないですから。

7.Game DesignポケモンHxHの念能力( 戦闘システムの作成)

今週は召喚したMonsterが攻撃するようにします。と言っても何をしたら良いのか分かりません。そこから考えます。

7.1 Monsterに攻撃させるためには

思い付くままに書き込んで後から整理します。

Game ModeのEvent Player Actionが発動したらLevel BP上のPlayer側のMonster BPが対戦相手側のMonster BPを攻撃します。

f:id:kazuhironagai77:20220206225938p:plain

具体的には

  • 左翼のMonsterが右翼のMonsterを攻撃
  • 中央のMonsterが中央のMonsterを攻撃
  • 右翼のMonsterが左翼のMonsterを攻撃

を行います。

それぞれの戦闘では

  • 攻撃中である事を示すWidgetの表示
  • ダメージの計算
  • 攻撃した結果、相手のMonsterは死んだのかの確認
  • Widget上で結果を表示

うーん。

成程。問題点がはっきりして来ました。Monsterが攻撃する前に相手のMonsterが生きているのかの確認が必要です。

更に相手のMonsterが死んでいた場合、別な相手と戦うのか対戦相手の魔術師に攻撃するのかを決める必要もあります。

今週は、Monsterに攻撃させるのが目的ですので、どれか一体のMonsterが死んだ時点で戦闘は終了にします。仮組みです。

これなら戦闘前に対戦相手のMonsterが生きているかの確認をしなくてすみます。

それぞれの戦闘が終了したら、

  • 戦闘で相手Monsterを倒した場合
  • 戦闘で相手Monsterが生き残った場合

の2パターンについて考える必要があります。

<戦闘で相手Monsterを倒した場合>

Game Mode BPのPlayer Win変数に、Playerが勝った時はTrue、対戦相手が勝った時はFalseをセットします。

そして、Event Fight Overを発動します。

<戦闘で相手Monsterが生き残った場合>

次の戦闘に移行します。

  1. 左翼のMonsterが右翼のMonsterを攻撃
  2. 中央のMonsterが中央のMonsterを攻撃
  3. 右翼のMonsterが左翼のMonsterを攻撃
  4. Playerが先攻の場合は、Monsterの攻撃のTurnPlayerが後攻の場合は、次のTurnの開始

になります。

ああ、そうでした。Player側が攻撃の場合を想定していたんです。すっかりその事忘れていました。

対戦相手が攻撃の場合も考える必要がありました。

対戦相手が攻撃の場合は基本的にはPlayer側が攻撃した時と同じになるはずです。

<ダメージの計算方法>

これ考えるの忘れていました。

<<ジャンケンで勝った場合>>

攻撃力が2倍になります。

ダメージは(HP-攻撃力*2)で計算します。

<<ジャンケンであいこもしくは負け>>

攻撃力はそのままです。

ダメージは単純に(HP-攻撃力)で計算します。

もう少し複雑な計算した方が戦闘の実態を表すかもしれませんが、取りあえずはこれで行きます。

<Monsterが死んだかどうかの判定>

HPが0になったら死亡です。

このAlgorithmなら実装出来るがします。やってみましょう。

7.2 Monsterに攻撃させる実装を組む

Level BP上にPlayer が召喚したMonsterを管理するMonster BPの変数と対戦相が召喚したMonsterを管理するMonster BPの変数が無いです。

f:id:kazuhironagai77:20220206230102p:plain

何で?と思って調べたらMonsterをSpawnした後にそこで生成したMonster BPのInstanceの変数を作ってなかったです。

f:id:kazuhironagai77:20220206230118p:plain

作り直します。

f:id:kazuhironagai77:20220206230138p:plain

更にそれぞれの変数に値をAssignします。

f:id:kazuhironagai77:20220206230200p:plain

Game Mode BP内にEvent to Level Player Monster Fightを作成します。

f:id:kazuhironagai77:20220206230219p:plain

このEvent DispatcherをEvent Player Actionが発動したら呼びます。

f:id:kazuhironagai77:20220206230237p:plain

Level BPのEvent Begin PlayにこのEvent DispatcherをBindします。

f:id:kazuhironagai77:20220206230250p:plain

このEvent Dispatcherは以下に示したEvent Player Monster AttackにBindしました。

以下にEvent Player Monster Attackの実装を示します。

f:id:kazuhironagai77:20220206230311p:plain

Event Player Monster Attackは個々のMonsterがそれぞれの相手に攻撃します。

f:id:kazuhironagai77:20220206230324p:plain

対戦相手のMonsterが死んだ時はGame Mode内のEvent 、Fight Overを発動します。

f:id:kazuhironagai77:20220206230355p:plain

それ以外の時は、Playerが先攻の時はGame Mode内のEvent, Opponent Action、Playerが後攻の時はGame Mode内のEvent、Event Choose Firstを発動します。

f:id:kazuhironagai77:20220206230417p:plain

これで完成したと思ったらEvent Player Actionで作成されるWidget, W Player Attackの実装を変更する必要がある事に気が付きました。

f:id:kazuhironagai77:20220206230435p:plain

以下の部分を外しました。

f:id:kazuhironagai77:20220206230452p:plain

この部分はLevel BPのEvent Player Monster Attack内で実行する事になったので外しました。

更にW Player AttackウィジェットはEvent Player Monster Attack内からRemoveされるようにしました。

f:id:kazuhironagai77:20220206230512p:plain

一応これで出来たはずです。

テストします。

このままだと何が起きているのか不明なのでPrint Stringをテスト用に追加します。

f:id:kazuhironagai77:20220206230528p:plain

f:id:kazuhironagai77:20220206230538p:plain

Errorが

f:id:kazuhironagai77:20220206230754p:plain

直します。

先攻の魔術師が召喚したMonsterの正体を現す時に生成したMonsterを先程作成した変数にAssignするのを忘れていました。

f:id:kazuhironagai77:20220206230809p:plain

f:id:kazuhironagai77:20220206230817p:plain

直しました。

もう一回テストします。

今度はErrorは無いです。

f:id:kazuhironagai77:20220206230836p:plain

Print Stringも正常なコメントを表示しています。

一応、出来た事にします。

< MonsterのPropertiesを調整する>

f:id:kazuhironagai77:20220206230859p:plain

今のAttack PointとHPだと一回攻撃すれば大体勝てます。これだとテスト数が少なくなってBugを発見出来ません。HPを今だけ10倍にします。

f:id:kazuhironagai77:20220206230929p:plain

これでテストします。

何回も試しましたが問題なく出来ました。

幾つかのScreenshotを以下に示します。

f:id:kazuhironagai77:20220206231002p:plain

f:id:kazuhironagai77:20220206231018p:plain

7.3 来週の予定

来週はPlayerが攻撃している時に表示されているWidgetを改良して

f:id:kazuhironagai77:20220206231042p:plain

f:id:kazuhironagai77:20220206231050p:plain

どのMonsterがどのMonsterを攻撃したのかが分かるようにします。

更に全てのMonsterのHP/MHPなどのParameterも表示するようにしてPlayerのMonsterが攻撃している時に、何が起きているのかをUserに分かるようにします。

今週はここまでです。

8. UE5Naniteの勉強

先週、Ryan Laley氏のUnreal Engine 5 Tutorial - Create Nanite Meshes [10] を勉強して始めて自分でNaniteのStatic Meshを作成しました。

f:id:kazuhironagai77:20220206231134p:plain

前に勉強したNanite Virtualized Geometry [11]を見直して関連している部分をもう一回勉強します。

先週やった内容と全く同じ事が書かれている箇所がありました。

f:id:kazuhironagai77:20220206231151p:plain

2021-12-20のBlogでこの部分を勉強していますね。

f:id:kazuhironagai77:20220206231207p:plain

これだけしか記録してないです。

まあ間違った事を言っている訳ではないですが。

今週のNaniteの勉強はこれだけで終わりにしてBlenderの勉強を一寸だけします。

9.Blenderの勉強

2022-01-31のBlog

f:id:kazuhironagai77:20220206231228p:plain

と述べましたが、私の要望にぴったしのTutorialが見つかったので急遽、勉強する事にします。

Imphenzia氏のLearn Low Poly Modeling in Blender 2.9 / 2.8 [11] です。

f:id:kazuhironagai77:20220206231255p:plain

これで勉強する事にします。

9.1 Blenderを最新版に変更する

今、PCに入っているBlenderを見たら一応2.8でした。最新のBlenderは3.01のようです。Tutorialは2.9、2.8でやっています。

3.01がどれくらい2.9と違うのか全く分かりません。

これをInstallします。

f:id:kazuhironagai77:20220206231319p:plain

一瞬で出来ました。

これで勉強します。

9.2 Basicを勉強する

Imphenzia氏のLearn Low Poly Modeling in Blender 2.9 / 2.8 [11]のTutorialはSection毎に細かく分かれているのでこれに沿って勉強します。

f:id:kazuhironagai77:20220206231341p:plain

一番最初のSectionはBasicです。

どうやらここはBlenderのView画面の操作方法の解説のようです。

<MouseのScroll Wheelを押したままDrag

原点を中心にして回転します。

f:id:kazuhironagai77:20220206231425g:plain

これは選択したObjectを中心に回転している気もしたので確認のためにLightを選択して同じ事を試してみました。

f:id:kazuhironagai77:20220206231455g:plain

原点を中心に回転しています。

ちなみにUEだと同じ操作はどうなるのかと言うとUE5で試してみたところ、こんな動きをしました。

f:id:kazuhironagai77:20220206231527g:plain

あーこれは後で混乱しますね。

<Shift + MouseのScroll Wheelを押したままDrag

f:id:kazuhironagai77:20220206231559g:plain

この動きをPanningというのか。

と言うとさっきのUE5の動きもPanningですね。

そうなるとやっぱりUE5でこれをやった時の動きも気になります。

うーん。

全然進まない。けど試してみます。

UE5でShift + MouseのScroll Wheelを押したままDragしたら、Shiftなしの動きと同じでした。

後、UEのMaterialのPannerノードの動きはこれとは一寸だけ違いますね。(2022-01-31のBlogにPannerノードについてはまとめがあります。)

f:id:kazuhironagai77:20220206231624p:plain

<MouseのScroll Button をScroll

Zoom in Zoom Outします。

これはUE5でも同じです。

<Key Padの1など>

f:id:kazuhironagai77:20220206231649p:plain

うーん。これは上面図なのか?

f:id:kazuhironagai77:20220206231708p:plain

いや、正面図?

TutorialのBlender

f:id:kazuhironagai77:20220206231724p:plain

Yに-が付いてないですね。

OrthographicとPerspectiveの切り替えが5で出来るそうです。そう言えば昔Blenderを使用した時、5で切り替えたりしてました。完全に忘れていました。

<Properties Area

以下に示したBoxをProperties Areaと言うそうです。

3D  Modelingでは赤で丸したSpannerの部分しか使用しないそうです。

f:id:kazuhironagai77:20220206231745p:plain

こういう情報が欲しいんです。

うーん。このTutorial良さそうです。

<N Key

N Keyを押すと以下のboxが表示されます。

f:id:kazuhironagai77:20220206231811p:plain

絶対忘れます。このやり方。

このTutorial、1時間以上あるんですが、まだ1分しかみてません。こんなの絶対今日中には終わりません。

<MouseのLeft Button

Objectを選択する時に使用します。これはUEでも一緒のはずです。もう試しませんが。

じゃMouseのRight Buttonは?となりますが、このTutorialではRight Buttonは使用しないから知らんで良い。と言ってました。ありがたい!

<Delete Key

選択したObjectを消します。

これは多分全部の3dで同じでしょう。

9.3 Colorizing Low Poly Objectを勉強する

これやったら今週のBlenderの勉強は終わりにします。

無理でした。一時間でBlenderを使いこなすようになるなんて。

コツコツやる事にします。

Tutorial提供のTextureはDownloadしました。

f:id:kazuhironagai77:20220206231851p:plain

Shading Tabを開きます。

f:id:kazuhironagai77:20220206231907p:plain

TextureをDropして以下の様に組みます。

f:id:kazuhironagai77:20220206231921p:plain

次にUV Editing Tabを開きます。

f:id:kazuhironagai77:20220206231937p:plain

f:id:kazuhironagai77:20220206231943p:plain

Tutorialだとここから以下の所から

f:id:kazuhironagai77:20220206232002p:plain

Viewport Shadingを開いてTextureを選択しています。

f:id:kazuhironagai77:20220206232016p:plain

これが見つからない。

見つかりました。

Tutorialの様に左の画面を小さくしたら出て来ました。

f:id:kazuhironagai77:20220206232035p:plain

f:id:kazuhironagai77:20220206232042p:plain

Boxの色です。

f:id:kazuhironagai77:20220206232102p:plain

次にAを押して以下のUVを全部選択します。

f:id:kazuhironagai77:20220206232122p:plain

Aを押すと全部選択してくれるみたいです。

Sを押してScaleにします。更に0を押してサイズを0にします。

こんなになっています。

f:id:kazuhironagai77:20220206232142p:plain

Gを押すとこのオレンジの点を動かせます。

Tutorial通りに緑の上に移動させました。

f:id:kazuhironagai77:20220206232202p:plain

Cubeが緑色になりました。

f:id:kazuhironagai77:20220206232220p:plain

今度はCubeの一つの面の色だけ変更します。

f:id:kazuhironagai77:20220206232239p:plain

選択は出来たんですが、Tutorialだと面をクリックして選択しています。私のはVertexを全部選択しないと面の選択が出来ません。

以下の部分の選択されている箇所がTutorialと私のBlenderでは違っていました。

f:id:kazuhironagai77:20220206232303p:plain

Tutorialと同じにしたら左クリックで一発で面が選択出来ました。

f:id:kazuhironagai77:20220206232323p:plain

左の画面でGを押してオレンジの点を移動させました。

f:id:kazuhironagai77:20220206232350p:plain

選択した面の色だけが変化しました。

この後、Game EngineにこのBoxをExportする場合、別なUV Layoutが必要になる場合があるそうです。やり方は後で解説するそうですが、その事を覚えておいてと言っていました。

<Shinny Viewport Setting

休憩したら元気が戻って来たのでもう一寸だけやる事にします。

今度はViewportをImphenzia氏のそれと同じ設定にする方法だそうです。

Viewport ShadingのShadowにcheckを入れます。

f:id:kazuhironagai77:20220206232416p:plain

更にその下のCavityにもcheckを入れます。

f:id:kazuhironagai77:20220206232436p:plain

そしてTypeをBothに変更します。

f:id:kazuhironagai77:20220206232454p:plain

そして下の値をMaxまで上げます。

f:id:kazuhironagai77:20220206232511p:plain

こうする事でEdgeが光って見えるそうです。

f:id:kazuhironagai77:20220206232536p:plain

よーく見ると少しだけ光っています。

更にBackface CullingにCheckを入れます。

f:id:kazuhironagai77:20220206232555p:plain

これにCheckを入れておくと間違った方向を向いた面があった場合分かるそうです。

UEのMaterialのTwo Sideの逆ですかね。この機能は。

説明を聞く限りそのようです。

F3を押してFlip Normalと押すと選択した面のNormal を逆に出来るそうです。

やってみます。

f:id:kazuhironagai77:20220206232614p:plain

以下の様になりました。

f:id:kazuhironagai77:20220206232641p:plain

もう一回やりました。

f:id:kazuhironagai77:20220206232701p:plain

元に戻りました。

<Object Mode vs. Edit Mode

これは前勉強しました。

Tab keyで切り替えれるそうです。

以下の部分の表示が切り替わりますね。

f:id:kazuhironagai77:20220206232722p:plain

Objectを操作する時はObject Mode、Object内のGeometryを操作する時はEdit Modeだそうです。

<Basic Low Poly Editing

Vertex、Edge、そしてfaceの選択が出来ます。

f:id:kazuhironagai77:20220206232743p:plain

これさっき弄ったやつですね。

Hot keyの123でも切り替えが出来るそうです。試したら出来ました。

更にShift + MouseのLeft Buttonで複数の選択が出来るそうです。

f:id:kazuhironagai77:20220206232800p:plain

出来ますね。ただこのTutorialではこれを使用する事はないそうです。

ここからCubeのGeometryを編集します。

Cubeの上面を選択した状態で、Gを押すと以下に示したように自由に上面を動かせるようになります。

f:id:kazuhironagai77:20220206232820p:plain

ただこのやり方では望みの方向に選択した面を動かす事は出来ません。

そこでShift + Space でGだそうです。

f:id:kazuhironagai77:20220206232839p:plain

X,Y,Z軸を表す矢印が表示されました。

所が、一回は表示されたんですがそれ以降出なくなってしまいました。

良く分からないんでBlenderを再起動させます。

今度は出ました。

f:id:kazuhironagai77:20220206232858p:plain

Shift + Spaceで以下のboxが表示されます。そこからMouseでMoveを選択して左Buttonでクリックします。すると出来ました。

f:id:kazuhironagai77:20220206232919p:plain

Gを押しても反応しません。MouseでClickする必要があります。

以下の所でDefaultにMoveを選択する事で一々、Shift + SpaceそしてGを押す必要が無くなるそうです。

f:id:kazuhironagai77:20220206232941p:plain

どういう事と思って別な面を選択したら

f:id:kazuhironagai77:20220206232958p:plain

選択するだけで矢印が表示されるようになりました。

再起動してEdit Modeに変更した後、以下の設定をしました。

f:id:kazuhironagai77:20220206233024p:plain

面を選択すると矢印が表示されます。

f:id:kazuhironagai77:20220206233041p:plain

こっちは簡単ですね。

次はVertexを一個だけ選択した時です。

f:id:kazuhironagai77:20220206233100p:plain

Gを押すと選択したVertexを自由に動かせます。

f:id:kazuhironagai77:20220206233118p:plain

あんまり綺麗じゃないですが出来ました。

GGを押すと選択したVertexをEdge上に自由に動かせます。

f:id:kazuhironagai77:20220206233134p:plain

この機能が後で役に立つそうです。

<Scalingについて>

Sを押すとScalingになります。

f:id:kazuhironagai77:20220206233153p:plain

一つの面だけ選んでScalingをしたらどうなるのか気になったので試してみました。

f:id:kazuhironagai77:20220206233211p:plain

選択した面のサイズだけ変化しました。

Scalingをする時はCursorをObjectから離れた状態ですべきだそうです。Object内にCursorを置いた状態でScalingをすると一寸移動しただけで選択した面が凄く小さくなったり大きくなったりするそうです。

これは面白い。試してみます。

f:id:kazuhironagai77:20220206233237p:plain

面というより面の中心からの距離ですね。

確かにScalingを指定する切り取り線が凄い短いです。

今度は遠くにCursorを置いてSを押しました。

f:id:kazuhironagai77:20220206233304p:plain

凄い。

全然違います。動かすと非常に微妙なサイズの変化まで調節出来ます。

<Pivot Pointについて>

Period keyを押すとPivot Pointが表示されます。

f:id:kazuhironagai77:20220206233322p:plain

なんじゃこれ?

良く分かりませんが凄いです。

Tutorialの解説によると以下のように2つの面を選択して

f:id:kazuhironagai77:20220206233338p:plain

SでScalingをすると以下に示した様に全部の面のサイズが変化します。

f:id:kazuhironagai77:20220206233402p:plain

これをPeriod Keyを押してPivot Pointを表示させIndividual Originsを選択すると

f:id:kazuhironagai77:20220206233440p:plain

選択した面のみのSizeが変化するようになります。

f:id:kazuhironagai77:20220206233454p:plain

うーん。面白い。

<E KeyでExtrude

f:id:kazuhironagai77:20220206233516p:plain

選択した面を飛び出すやつです。

これは覚えていました。

Tutorialの時間で丁度10分を超えたので今週はここで中止します。

Tutorialは全部で1時間23分なので最低8回は勉強する必要がありますね。2,3カ月はかかりますね。地道に勉強する事にします。

10.まとめと感想

今週は、RPGのProjectそのものは弄りませんでした。Prologueがある程度完成しないと実際のRPGのPrologueは変えられないです。Prologueをもっと頑張る事にします。

11.参照(Reference

[1] Epic Games. (n.d.). Events and Event Handlers Overview. Unreal Engine Documentation. Retrieved February 6, 2022, from https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Niagara/EventHandlerOverview/

[2] CGHOW. (2021, December 31). Happy New Year ! | Download Free UE4 Niagara Project [Video]. YouTube. https://www.youtube.com/watch?v=n-GuGpByALQ

[3] Andurlekar, H. [Hrishikesh Andurlekar]. (2020, May 18). UE4 4.25 Niagara Event Handler Simplest Example [Video]. YouTube. https://www.youtube.com/watch?v=wJ5o8mxeyXY

[4] HEYYO CG. (n.d. -a). 【UE4.26】Niagara Advanced 解説基礎編~Particle Attribute Reader~ – HeyYo CG. Retrieved February 6, 2022, from https://heyyocg.com/ue4-26-niagara-advanced-particle-attribute-reader-basic/

[5] Cloward, B. [Ben Cloward]. (2022, January 20). Triplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [Video]. YouTube. https://www.youtube.com/watch?v=VUoI_IESK7U&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=30

[6] Smart Poly. (2020, May 19). How To Make A Massive Open World Map In Unreal Engine 4 [Video]. YouTube. https://www.youtube.com/watch?v=HQUC0Gejmo4

[7] Smart Poly. (2021, June 3). Unreal Engine 5 | Open World Tutorial Using World Partition [Video]. YouTube. https://www.youtube.com/watch?v=efN4bGbzr78

[8] Epic Games. (n.d.-b). Landscape Expressions. Unreal Engine Documentation. Retrieved February 6, 2022, from https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Materials/ExpressionReference/Landscape/#landscapelayercoords

[9] Epic Games. (n.d.-d). Open World Tools. Unreal Engine Documentation. Retrieved February 6, 2022, from https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/OpenWorldTools/

[10] Laley, R. [Ryan Laley]. (2021, June 1). Unreal Engine 5 Tutorial - Create Nanite Meshes [Video]. YouTube. https://www.youtube.com/watch?v=YucYfUbazKY

[11] Epic Games. (n.d.-c). Nanite Virtualized Geometry. Unreal Engine Documentation. Retrieved February 6, 2022, from https://docs.unrealengine.com/5.0/en-US/RenderingFeatures/Nanite/

[12] Imphenzia. (2020, June 25). Learn Low Poly Modeling in Blender 2.9 / 2.8 [Video]. YouTube. https://www.youtube.com/watch?v=1jHUY3qoBu8