<前文>
<勉強する方法について>
ゲームの専門学校に通うような人は勉強するのが苦手な人が結構いるそうです。
ここで注意して欲しいんですが、勉強が苦手じゃなくて勉強するのが苦手な人です。勉強が苦手と言う意味は英語とか数学の成績が悪い事ですが、勉強するのが苦手と言う意味は机に向かう事が出来ないとか、勉強するために机に座ってもYouTubeを見てしまうとか言う意味です。
私はこの勉強するのが非常に得意で、休日のように丸一日空いてる日なら10時間ぐらいぶっつづけで勉強出来ますし、平日なら空いてる時間によりますが1~2時間ぐらいなら毎日勉強する事も出来ます。
ところが最初からこうだった訳ではなく中学生の時は、勉強するために机に座ると小説読み出しちゃって全く勉強しませんでした。勉強するのが非常に苦手でした。
それでまあ紆余曲折あってその辺は長いので端折りますが、今は勉強する事は非常に得意に成りました。
その経験を踏まえて勉強するのが苦手な人にどうしたら勉強をする事が出来るようになれるかのAdviceを送ります。
アメリカ人の良く言うmy two centsってやつですが一読の価値はあると思っています。
勉強するのが苦手な人はぜひ参考にして下さい。
勉強するのが苦手な人は、まず以下に示した「人が勉強する仕組み」を理解しましょう。
勉強する事が出来るようになるためには、左の円に書かれている2つの事が最初に必要になります。それはやる気と環境です。
勉強する環境とはズバリ時間と場所です。
勉強する時間が全く取れない状態では勉強する事は出来ません。よく寝る時間を削って勉強すると言う人がいますが無駄です。人間の体は頭脳労働の場合は6~7時間、肉体労働の人は8時間は寝ないと回復しないように出来ています。それをすると睡眠を削った時間だけじゃなくて残りの起きている時間全て無駄にしてしまいます。睡眠時間以外から勉強する時間を作る必要があります。遊ぶ時間を削る人もいますが、人間はストレスを解消する必要もあります。遊ぶ時間を削ると次に説明しますが、やる気が極端に減少する事になる場合が多いです。
寝る時間と遊ぶ時間を削らずに勉強する時間を確保する必要があります。
次に勉強する場所ですが、雑音はあまり問題にはなりません。逆に回りがうるさい程集中出来る人は結構います。場所で私が注意する点は主に2つです。温度とInternetです。
まずInternetにアクセス出来ない環境で勉強してはいけないです。YouTubeやTwitterばっかり見てしまうとかそういう問題があったとしてもInternetを使用しないで勉強しては駄目です。勉強する時は必ずInternetで勉強する内容の情報を出来るだけ集めるべきです。この理由結果の部分で詳しく解説します。
次に大切なのが温度です。人間は大体、周りの温度が25℃前後の時にもっとも能力を発揮出来ます。ところがここから2度ずれるともう80%位の能力しか出せなくなります。それでもほとんどの人が普通にやっていけているのは服を脱いだり着たりして適温の調節をしているからです。
一念発起して物置とか押入れで勉強始める人いますが、そういう人で挫折する人の多くがこの温度の問題を軽視しています。15℃とか35℃の場所で勉強する事は出来ません。
次に問題になるのがやる気です。
勉強しようと思った訳ですから、少なくともその瞬間はやる気はあったわけです。しかしいざ机に座るとInternetを3時間も見ちゃって勉強時間、無くなっちゃったと言う人は結構いると思います。
この対策ですが、短期と長期的な対策があります。
最初に長期的な対策になりますが、これは図の右側に書かれている結果です。結果を出す事です。良い結果が出ればやる気は出て来ます。しかも良い結果が出た事から来るやる気は長続きします。2か月とか3カ月と勉強を続ける事が出来る継続的なやる気を生み出します。
次に短期的なやる気がなくなる場合ですが、これは原因がストレスである場合がほとんどです。
ストレスは解消されない限り絶対に勉強出来ません。脳が勉強する事を断固拒否しますので、ストレスは必ず解消してから勉強は始める事にしましょう。勉強始める前に5分だけ休憩するとか、勉強終わったら必ず30分間遊ぶとか、人それぞれですが、勉強を始めるためにはストレスは必ず取る必要があります。
因みに私のストレス解消法はこの前文を書く事です。自分が渡辺昇一や山本義隆のような作家になったような気がして日頃のストレスがスッと消えてしまいます。
このストレスが無くても勉強する事自体がストレスになって勉強出来ない場合もあります。試験勉強なんかであまりにも膨大な量を一日で勉強しないといけなくなると勉強そのものがストレスになります。こういう時は半分だけ勉強する事にします。
人間は10の事をやるためには12位のやる気が必要なんです。10のやる気しかない時に10をやろうとすると必ずやる気が無くなって全く勉強出来なくなります。10のやる気がある時は5だけやるようにします。
次にInternet対策ですが、ストレスが過度になく勉強する気がある場合は、そんなにはTwitterやYouTubeに振り回される事は無くなります。
正しそれでもInternetの誘惑に負けがちな人は、Netで検索する時間と検索した内容を勉強する時間を分ける事をお勧めします。これを注意してやるとInternetの誘惑に駆られてTwitterなんかを読み始めると直ぐに自分で気が付いて軌道修正出来ます。
ここまでが勉強をするために必要な左側の円の内容になります。そして今まで話した内容に匹敵するぐらい大事になるのが右の円に書かれている結果です。
今度は結果について話します。
人間は自分が思っている以上に費用対効果に敏感で、費やしたエネルギー以上の何かが得られない場合、その事をやるのが嫌いになります。つまり勉強するのが苦手な人は勉強したけどその結果、望んだ結果が得られないので勉強する気が無くなった人達なんです。
じゃあ何で結果が出なかったのかと言うと、これも色々な原因がありますが、以下の3つがよく思い当たります。
- 望みが高すぎる。
- 勝負事で相手が優秀過ぎた。
- 出来レースで最初から勝てないようになっている。
これ下の二つはどうしようもないんです。別な分野でがんばるしかありません。
最初の望みが高すぎるですが、これは対策がある程度取れます。
対策1ですが、望みが高すぎるので低く設定する。です。
これ、診断するのは割かし簡単で、親と比較するんです。親が医者だったら医学部へ行くと言う望みは高すぎません。妥当な目標設定になります。親がスポーツ選手だったらプロのスポーツ選手を目指すのは高すぎる望みじゃないです。
しかしそうでない場合は望みが高すぎます。もっと低く設定し直しましょう。
ゲームの専門学校に来る人はあんまりこのタイプの高望みする人は居ませんかもしれませんが、任天堂のゲームを見てGraphicがPS2レベルだよね。とか文句言っている人はこのタイプに当たる可能性があります。Hello worldなんで出来てどうなるんですか?とかScratchなんで勉強する気になりません。とか言っていませんか?
対策2ですが、同じ結果が得られる別な分野を目指すです。
世界的なゲームを制作するProgrammerには成れないかもしれませんが、世界的なゲームを制作するDesignerなら成れるかもしれません。自分が得意な分野なら高い望みも妥当な目標になります。自分の才能や環境を見極めてその中で世界で一番に成れそうな分野があるのなら、その分野で頑張るんです。
はい。適切な目標が出来ると検討違いの目標から解放されますが、それですぐ結果が出るわけじゃないです。
結果を出すためには更に気を付ける問題があります。
ここからは一寸文句を言う人も出て来る内容になるので特別丁寧な言い方をする必要がありますが、事実なのでズバットと書いておきます。
教師、教材の質です。
ハッキリ言ってその辺のレベルの教材で勉強しても目を見張る上達なんて起きません。やるだけ無駄な成果しか出ません。
どんな分野でも世界のTop Levelから直接指導してもらった経験がある人なら知っているでしょうがそういう人の指導を受けるとマジで結果が出ます。
しかし悲しい事にそう言う人から直接指導してもらう事は普通の人では無理です。出会う事すらかないません。
そこでInternetの出番なんです。
Internetで検索して色々な人の解答を探すんです。それを比較してより正しい解答を作成する人、あるいはその人が作成したTutorialで勉強したら前より良い結果が出たとか、前より理解が進んだと思う人へドンドン乗り換えるんです。これを常にしておくとこの分野ならこの人の言う事聞いて置けば間違いないな。とかこの人のTutorialで勉強しておけば分からない分野でも大体理解出来るな。みたいな人のStockが出来ます。
これを使って勉強します。
はい、これで勉強するのが苦手な人も勉強を始められるようになります。
そして結果が出るようになると更にやる気もアップするし環境も更に良くなります。その結果、さらに良い結果が生まれて+のスパイラルが生まれます。そのまま続けると、気が付くと10時間ぐらい連続で勉強出来るようになります。ただ幾ら休日といえ、10時間も勉強に費やしていたら次の日に支障が生まれますし、他のやるべき事もかなり犠牲にする事になるのでその辺は調節して6~8時間位で止めておくべきでしょうが。
それでは今週の勉強を始めます。
<本文>
1.今週の予定
今週も先週と同じ内容でやっていきます。
- Niagara: Eventの検証
- Material :Projectionの勉強の続き
- Prologueの作成
- Open Worldの検証や他のMapの作成
- Game Design:ポケモン+HxHの念能力( 戦闘システムの作成)
- UE5:Naniteの勉強
- Blenderの勉強
2.Niagara: Eventの検証
今週は兎に角、EventとEvent Handlerについての勉強をします。先週、作成したEvent Handlerの挙動に納得出来ない部分が何か所かあり、それをきちんと理解したいです。
2.1 先週の復習
先週、何を勉強したのかほぼ忘れてしまったので復習からします。
先週のBlogを読み直します。
思い出しました。
先々週、CGHOW氏のHappy New Year ! | Download Free UE4 Niagara Project [1]の実装を見てたら、Eventの受け取り方に2種類あってそれの使用方法が良く分からないのでEventを勉強し直したんです。
そしたら、Spawn Particle From Other Emitter Moduleを使用する方法はParticle Attribute Readerと言われる技術で、Eventとは別な方法でEmitter間のやり取りをしている事が分かりました。
本当は、このParticle Attribute Readerを今週勉強する予定だったのですが、先週、EventとEvent Handlerの使用方法を勉強していたら良く分からない問題が発生しました。
以下にその問題をまとめます。
<Event HandlerのあるNiagara EmitterのEmitter Update SectionのLife Cycle Modeはsystemに変更すべきか?>
これ、先週、勉強し直したUE4 4.25 Niagara Event Handler Simplest Example [2] ではSystemにしないと正しくEventを受け取らないんですが、CGHOW氏のHappy New Year ! | Download Free UE4 Niagara Project [1]ではselfになっています。
Emitterの寿命をEmitter自身に管理させるのがSelfでSystem上で管理するのがSystemと言う事は分かっています。
でもそれがどうしてEvent Handlerに影響を与えるのかと、UE4 4.25 Niagara Event Handler Simplest Example [2] ではSystemにしないと正しくEventを受け取らないのにHappy New Year ! | Download Free UE4 Niagara Project [1]ではselfでも正しくEventを受け取れるのかの理由が分かりません。
<Emitter Update SectionのEmitter State ModuleのLoop Durationの値をEventとEvent Handlerの両方で同じ値にする必要があった。>
これは一緒にしないとどんな問題が発生したのか書かれていません。先週の事ですが覚えていません。まずどんな問題が発生したのかの確認をしてから原因を検証します。
<Generate Death Event ModuleのGap Correction Amountの値>
これは先週は疑問としては書いていませんが、勝手に0にセットしています。Tutorial通りに1.5にセットした場合との違いを確認します。
2.2 Tutorialの確認
先週、実装したUE4 4.25 Niagara Event Handler Simplest Example [2]を見直していて本当にしっかりとUE4 4.25 Niagara Event Handler Simplest Example [2]を勉強したのかの疑問が出て来ました。
一番最初にUE4 4.25 Niagara Event Handler Simplest Example [2]を勉強した2021-05-17のBlogには
のように最初の爆発を消すためにTimelineのひし形を消す必要があると書かれていますが、先週、実装したUE4 4.25 Niagara Event Handler Simplest Example [2]では
しっかりひし形が残っています。
2021-05-17のBlogに書かれていた方法でひし形を消したら
最初の爆発は無くなりましたが、最初の2秒間はEvent側のEmitterも何もしなくなりました。
これはもう一回、UE4 4.25 Niagara Event Handler Simplest Example [2]を勉強し直した方が良い気がします。
2.3 先週作成したNSで検証する
先週作成したNS
は、最初の2秒間何もしないと言う問題がありますが一応、EventのSpriteが死ぬとEvent HandlerのEmitterがParticleを発生するとEvent の原則は達成しています。
これを使用して色々検証する事にします。
<Spawn Rate>
最初に、Emitter Update SectionのEmitter State ModuleのLoop Durationの値について検証しようと思ったんですがそう言えばSpawn Rate Moduleの値はどうだったのかと思いこっちを先に調べる事にします。
Eventを発する側のEmitterのSpawn Rateは0.5にセットされています。
Event Handlerのある方のSpawn Rateは
あれ、Spawn Rate Moduleがない。
うーん。
覚えていない。いつ消したんだろう。
それは兎も角、Eventを発する側のEmitterのSpawn Rateの値を変えてみます。1.0にしてみました。
Spawnの発生速度が0.5秒に一回になりましたが、それ以外の変化はないです。
Eventを発する側のEmitterのSpawn Rateの値の変化はEventの結果には何の影響もないみたいです。
<Emitter Update SectionのEmitter State ModuleのLoop Durationの値>
はい。それではEmitter Update SectionのEmitter State ModuleのLoop Durationの値についての検証をします。
先週の実装では、このEmitter State ModuleのLoop Durationの値をEvent側のEmitterとEvent Handler側のEmitterで同じにする必要があると書かれていました。
Event側のLoop Durationです。
Event Handler側のLoop Durationです。
確かに同じ値になっています。
最初にこの値を変化させて、Emitter State ModuleのLoop Durationの値をEvent側のEmitterとEvent Handler側のEmitterで同じにする必要があるのかの確認をします。
その前にParticle Spawn SectionにあるInitialize Particle Moduleの
Life timeが2.0にセットされています。
これについて検証しておきます。
まず、Particle Spawn SectionにあるInitialize Particle ModuleのLife TimeはParticle一個一個の寿命でしょう。ではEmitter Update SectionのEmitter State ModuleのLoop DurationがParticleより短くなったらどうなるんでしょうか?
多分、Particleも消滅すると思います。
これから確認します。
Event HandlerのEmitterを消して
EventのEmitterだけを表示します。
Emitter State ModuleのLoop Durationの値を
に変更してテストします。
最初にControlとしてLoop Durationが2の時の結果を記録します。
Timelineが0の時です。
Particleは何も現れていません。
1.04 の時
Particleが現れました。
これは1.0の時に現れるParticleが誤差で1.04に現れているんでしょうか?
次に2.06で
二つ目のParticleが発生しました。
次に3.05で
最初に発生したSpriteが消滅し、同時に三番目のSpriteが誕生しました。
後はこれを延々と繰り返します。
Loop Durationが1の時です。
Timelineが1.05の時にSpriteが誕生しました。
1.03かもしれませんが、1.03に矢印を合わせられないので確認出来ません。多分同じでしょう。
2.05の時です。
新しいParticleが生成されました。
更に前に生成されたParticleは消えずに残っています。
あれ、Emitter Update SectionのEmitter State ModuleのLoop Durationが1にセットされたのでEmitter自体の寿命が1秒になったと思ったんですが。
この後、ずっと見ましたが、結果はLoop Durationが2にセットされた時と全く同じでした。
うーん。
これはLoop Durationが実はEmitterの寿命を表していないのか、あるいはParticleはEmitterの寿命とは関係なく自身の寿命を持つのかもしれません。
それは分かりませんが、Loop Durationの値とParticle Spawn SectionにあるInitialize Particle ModuleのLife timeの値は、少なくともLoop Durationの値を2から1に変化した事で、干渉しあう事はなさそうです。
はい。
それではEvent側のLoop DurationとEvent Handler側のLoop Durationの値が異なるとEvent Handlerの挙動が変化するのかを確認します。
Event側のLoop Durationを1にセットしてEvent Handler側のLoop Durationは2のままにします。
結果です。
全く問題ないです。
この後、Loop Durationの値を色々変えて見ましたが、何の変化もありませんでした。
よって結論としてはLoop Durationの値はEventとEvent Handlerの関係に何の影響も与えない。となりました。
うーん。先週の実験結果はどうして起きたんでしょうか?
先週の結果が再現出来ないのでこれ以上の検討は出来ません。ここでLoop Durationの値の検証は終わりにします。
<Event HandlerのあるNiagara EmitterのEmitter Update SectionのLife Cycle ModeはSystemに変更すべきか?>
今はSelfにセットされています。
がなんの問題もありません。
Systemに変更してみます。
結果です。
全く問題ないです。
これはEvent Handler側のEmitter Update SectionのEmitter State ModuleのLife Cycle Mode をSystemに変更しないときちんと起動しないTutorialのUE4 4.25 Niagara Event Handler Simplest Example [2]を使用して検証する必要がありますね。
後でやる事にします。
<Generate Death Event ModuleのGap Correction Amountの値>
Particle Update SectionのGenerate Death Event ModuleのGap Correction Amountの値ですが
現在は0にセットしています。
Cursorを合わせると以下の説明が表示されます。
Possible Event DelayがもしEventが何らかの原因でLagが生じた場合を言っているのなら、Lagが生じない場合は関係ないと考えられます。
Possible Event Delayが、Eventが何らかの原因でLagが生じた場合以外を言っているのなら、何を言っているのか不明なので現時点での回答は出来ないです。
Tutorialの値である1.5に変更しましたが、何らかの変化を認識する事は出来ませんでした。
<検証結果のまとめ>
まずEvent State ModuleのLoop Durationの値がEvent側のEmitterとEvent Handler側のEmitterで同じにしないといけないと言う先週の結果は確認出来ませんでした。どのようにLoop Durationの値を変えても問題なくEventが伝わります。
更にEvent State ModuleのLife Cycle ModeがSystemでもSelfでも問題なかったです。これはEventの勉強をしたTutorialであるUE4 4.25 Niagara Event Handler Simplest Example [2]では問題が発生したはずなので後で確認します。
最後に、Generate Death Event ModuleのGap Correction Amountの値ですが、これがEventが何らかの原因でLagが生じた場合を想定してる値なら、Lagが生じない状態では0でも1.5でも問題ないはずです。そうでないのなら現時点では何をしているのか全く不明なので検証しようがないです。値を変化させた事によるEventの変化は観察されませんでした。
2.4 もう一回、UE4 4.25 Niagara Event Handler Simplest Example [2]を勉強する
大体、Eventの仕組みについては理解出来ましたが、このTutorialでEvent State ModuleのLife Cycle ModeをSystemに変更する必要があった理由と、Generate Death Event Moduleだけではなく他のEvent Moduleの作成方法も確認しておきたいのでもう一回、このTutorialをやります。
今度は全部、完全に同じに再現します。
最初にNiagara EmitterからFountain Templateを使用してNE_Event、Omni-directionalを使用してNE_EventHandlerを作成しました。
更にEmptyのNSを作成してNS_EventTestと名付けました。
NS_EventTestを開き、先程作成したNiagara EmitterであるNE_EventとNE_EventHandlerをTimelineにDrag and Dropで追加します。
NE_EventのInitialize Particle Moduleの
Life timeを以下の様にセットしました。
次にNE_EventHandlerのTimelineにあったひし形の印を消しました。
これがあるとNE_EventHandlerは勝手にEmitterを開始してしまいます。Eventを受け取った時以外はEmitterを発動して欲しくないのでこの手順は絶対に必要です。
次にEventを送る設定をします。
Particle Update SectionにGenerate Death Event Moduleを追加します。
Errorが表示されています。
Persistent IDにチェックを入れろって言っています。
Emitter Setting SectionのEmitter Properties Moduleの
Requires Persistent IDsにチェックを入れます。
Errorが消えました。
今度はEventを受け取るModuleをES_EventHandlerに追加します。
Event Handler SectionにEvent Handler Properties moduleを追加します。
設定は以下のようにします。
見やすいようにParticleの色を赤くします。
結果です。
EventのParticleが死んだ時にEvent HandlerのEmitterが発動していません。
更に最初の一回しかEvent HandlerのEmitterが発動していません。
最初の問題であるEventのParticleが死んだ時にEvent HandlerのEmitterが発動していないのはReceive Death Event Moduleが使用されていないからだそうです。
Event Handler SectionにReceive Death Event Moduleを追加します。
EventのParticleが死んだ時にEvent HandlerのEmitterが発動する様になりました。
今度は、最初の一回しかEvent HandlerのEmitterが発動していない問題を解決します。
Emitter Update SectionのEmitter State Moduleの
Life Cycle ModeをSystemに変更します。
きたあー。
ここでEvent HandlerのあるNiagara EmitterのEmitter Update SectionのLife Cycle ModeはSystemに変更すべきか?問題が発生したんです。
まずこのやり方で実際に結果が変化するのかを確認します。
変わりました。ずっとEventを受け取るようになりました。
うーん。
Selfに戻します。
ああ。
Loop BehaviorがOnceにセットされています。
先程の実験に使用したNSではLoop BehaviorはInfiniteにセットされています。
試しにInfiniteに変更しました。
ずっとEventを受け取るようになりました。
はあ。謎が解けました。
2.5 UE4 4.25 Niagara Event Handler Simplest Example [2]のCollusion、Location Eventを実装する
Generate Death Event Moduleの機能を停止させた後で、Particle Update SectionにGenerate Collision Event Moduleを追加します。
Errorが表示されるのでFixを選択します。
するとCollusion Moduleが追加されます。
その後で更にErrorが表示されます。のでFixを押すとCollusion Moduleの位置がSolve Forces And Velocity Moduleの前に移動してErrorが消えます。
今度は、Event を受け取る側を作成します。
NE_EventHandlerのEvent Handler SectionのEvent Handler Properties Moduleの
Sourceの設定をCollusionに変更します。
更にReceive Death Event Moduleの機能を停止してReceive Collusion Event Moduleを追加します。
Collusionを見るためにParticle Spawn SectionのInitialize Particle Moduleの
Lifetime Modeの設定を長くします。
結果です。
最後にPosition Eventをやります。
Collusion EventでやったようにParticle Update SectionのCollusion関連のModuleの機能を停止した後でGenerate Location Event Moduleを追加します。
Generate Location Event Moduleの以下の部分の設定についての解説は無かったです。
Eventを受け取る側を作成します。
NE_EventHandlerのEvent Handler SectionのEvent Handler Properties Moduleの設定を以下のように変更します。
更にReceive Collusion Event Moduleを外してReceive Location Event Moduleを追加します。
結果です。
Event側のParticleの位置が変化するたびにEventを発するそうです。そんな感じで赤いParticleが発射されていますね。
2.6 もう一度、Happy New Year ! | Download Free UE4 Niagara Project [1]のEventを確認する
これで流石にEventについては理解したはずです。
もう一回、Happy New Year ! | Download Free UE4 Niagara Project [1]のEventを見てみます。
Firework1を開きます。
Rockets Emitter、Burst Emitter、そしてBurst_tails Emitterの3つがあります。
Rockets EmitterのParticle Update Sectionを見るとGenerate Death Event Moduleがあります。
そしてBurst EventのEvent Handler Sectionを見るとEvent Handler Properties ModuleとReceive Death Event Moduleがあり
Event Handler Properties ModuleではRockets EmitterのDeath Eventを受け取るように指定されています。
はい。完全に理解出来ました。
次にBurst EmitterのParticle Update SectionにGenerate Location Event Moduleがありますが、
他のEmitterのEvent Handler SectionにはこのEventを受け取るModuleは何もセットされていないので
このEventは発動はしてますが何もしません。
Burst_tails EmitterのEmitter Update SectionにあるSpawn Particle from Other Emitter Moduleは
Particle Attribute Readerと言う全く違う技術でEmitter間のやり取りをしています。
これは来週勉強します。
3.Material : Projectionの勉強の続き
今週は先週勉強したTriplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [3] の理屈を検証してみます。
先週、どうしてそうやるのか全く理解出来なかった、Texture Sampleからの変換部分です。
ただしこの部分は難しすぎて、検証しても解けないかもしれません。のでTryするのは今週だけです。出来なかったら出来ないままProjectionのまとめに入ります。
3.1 仮説
闇雲にTryしても全く解けないのはほぼ確かでしょう。
この一週間である仮説を考えてみました。この仮説が正しいかどうかを検証します。
先週のNormal MapにおけるProjectionでTexture Sampleからの変換は2段階で行われています。何故、2段階なんでしょうか?
そこで思いついたのが以下の仮説です。
- 最初の変換は、Tangent SpaceからWorld Spaceへの変換を行っている。
- 次の変換は、Projectionによる投影したImageの向きを直している。
です。
まず、2番目の変換に対する仮説の根拠ですが、以下の実装が使用されている点です。
この部分の実装は先々週のBlogでやりましたがProjectionした場合、Textureの向きが半分だけ反転してしまう現象を直すために作成した実装と全く同じです。
つまり同じ目的でやっている可能性が高いです。これが2番目の仮説の根拠です。
そしてNormal MapはTangent Spaceで展開されています。Result NodeのNormalに接続する時に座標をWorld SpaceからTangent SpaceにTransform Vector ノードで変換しています。
と言う事はどこかでNormal Mapの座標をTangent SpaceからWorld Spaceに変換する必要があるはずです。
それをしているのが最初の変換だと思います。
今週はこれを検証します。
3.2 最初の変換を見る
以下にZ軸の変換を示します。
どこが最初の変換と次の変換の切り目なのかはこの実装だけ見ていると良く分かりません。
ここは仮にTexture SampleのRGBの順序を変換する部分がTangent SpaceからWorld Spaceへの変換と仮定します。そしてその後の計算はProjectionによる歪みを直す変換と仮定します。
Z軸の場合、Normal MapのRGBはそのまま接続されています。何の変換も必要ないんでしょうね。
Y軸の場合は、Normal MapのRGBはRBGとして接続されています。
そしてX軸の場合は、Normal MapのRGBはBRGとして接続されます。
そう言えば、Tangent Spaceの定義を忘れていました。それを調べます。
3.3 Tangent Spaceの定義
色んなサイトを読んで、私が理解した範囲のTangent Spaceの定義をまずまとめます。
まず以下の様なVerticesがあるとします。
それぞれのVertexはあるObjectを構成する一部なので当然Normal Vectorを保持しています。
それぞれのVertexのNormal Vectorを以下に緑の矢印で示します。
更にこれらのVertexはObjectの一部である曲面を構成する一要素であるのでTangentを求める事が出来ます。
これを以下に赤い矢印で示します。
上の曲線の傾きを求めたとなる赤の矢印の向きは少しおかしいですが、一応合っていると仮定して話を進めます。
Normal VectorとTangent は垂直に交わっています。のでこの二つからBi-Tangentを求める事が出来ます。Bi-TangentはNormal VectorともTangentとも垂直に交わるVectorです。これを青の矢印で表します。
これらがTangent SpaceのXYZ軸になります。
ひょっとするとこの解釈の時点で既に問題があるかもしれませんが、一応この解釈で正しいとして次の議論に進みます。
この定義だと2つ分からない部分があります。
最初の分からない部分は、UEだとどの座標軸がXYZに対応しているのか?です。これどの軸をX軸にしても自由ですよね。
まあこれは調べれば分かるはずです。後で調べます。
次の分からない部分はNormal Mapを展開したらNormal はNormal Mapの指定した値になるんじゃないの?と言う事です。となると新しく指定されたNormal VectorとObjectの曲面から計算されたTangentがOrthogonalに交わらなくなってBi-Tangentも計算出来なくなる気がします。
あっ。分かった。
Normal Mapに記録されているNormal VectorをObject上に展開するにはそのための座標軸が必要です。それがこのTangent Spaceなんです。
と言う事はNormal MapのNormal VectorはTangent Spaceの座標軸を決定する時には何も関係しないです。
Normal MapのNormal Vectorは以下の図の灰色の矢印で表したようにTangent Space上で展開されるはずです。
この灰色の矢印の値がこれからこのPixelかVertexのNormal Vectorの値になりますが、Tangent Spaceの軸が変化する事はないです。
後、必要な事はUEにおけるTangent Spaceの軸を確認する事です。
調べたけどよく分かりません。
UE4の場合の設定が知りたいんですが、それが見つかりません。
ふーん。
以下のMaterialを作りました。
Normal MapをBase Colorとして使用しています。
この結果を以下に示します。
まず青い部分ですが、この部分は完全な平らでObjectの表面と一致するはずです。
となるとこの部分のNormal VectorはTangent SpaceのNormal Vectorと一致するはずです。青と言う事はRGBのBでZ軸にあたります。となるとUEのTangent SpaceのNormal Vectorが示す軸はZ軸にあたると考えられます。
次にこのImageのデコボコになるはずの部分を見てみます。
最初に矢印で示した部分を見て下さい。
赤くなっています。
と言う事はこの矢印の方向がRの値、つまりX軸の値はRで表されています。
となると先程のTangent SpaceのCoordinateは以下の座標軸ではなく
こんな座標軸になるんでしょうか?
最後にGの値ですが下向きです。Y軸の値を表していますね。
やっぱりこの座標軸が正しいですね。
多分ですが、これがUEのTangent Spaceの座標軸でしょう。
3.4 Tangent SpaceとWorld Spaceの比較
以下のCubeのWorld Spaceの座標とTangent Spaceの座標を比較してみます。
<上面図>
Top ViewつまりZ軸を上から覗き込んだ状態です。
Tangent Spaceの座標がWorld Spaceの座標と完全に一致しています。
<正面図>
正面から覗いた時です。World Spaceのx軸から覗き込んだ状態になります。
World Spaceの座標が以下に示してあります。
World SpaceのX軸はTangent Spaceのz軸になっています。
World SpaceのY軸はTangent SpaceのX軸の逆向きです。
World SpaceのZ軸はTangent SpaceのY軸の逆向きです。
あれTangent SpaceからWorld Spaceに変換するのに既に逆向きが現れている。
<右側面図>
右側から覗き込んだ状態です。
World SpaceのY軸から覗き込んだ状態です。
World Spaceのx軸はTangent SpaceのX軸です。
World SpaceのY軸はTangent SpaceのZ軸です。
World SpaceのZ軸はTangent SpaceのY軸の逆です。
うーん。
逆から見た場合も調べてみます。
<底面図>
底面から見た場合です。
World Spaceの-z軸から見てる事になります。
World Spaceのx軸はTangent SpaceのX軸の逆です。
World SpaceのY軸はTangent Spaceのy軸です。
World SpaceのZ軸はTangent Spaceのz軸の逆です。
<後面図>
後ろから見た場合です。
World Spaceの-X軸から見ている事になります。
World Spaceのx軸はTangent SpaceのZ軸の逆です。
World SpaceのY軸はTangent SpaceのX軸です。
World SpaceのZ軸はTangent SpaceのY軸の逆です。
むむ。
何か法則性が見えて来ました。
<左側面図>
Left viewから見た図です。
World Spaceの-Y軸から見ている事になります。
World Spaceのx軸はTangent SpaceのX軸の逆です。
World SpaceのY軸はTangent SpaceのZ軸の逆です。
World SpaceのZ軸はTangent SpaceのY軸の逆です。
はい。
<CubeにおけるTangent SpaceとWorld Spaceの比較のまとめ>
World SpaceのZ軸の場合
- World Spaceのx軸はTangent SpaceのX軸です。
- World SpaceのY軸はTangent Spaceのy軸です。
- World SpaceのZ軸はTangent Spaceのz軸です。
World Spaceの-Z軸の場合
- World Spaceのx軸はTangent SpaceのX軸の逆です。
- World SpaceのY軸はTangent Spaceのy軸です。
- World SpaceのZ軸はTangent Spaceのz軸の逆です。
となりました。軸の向きを無視した場合
Z軸はWorld SpaceのXYZ軸とTangent SpaceのXYZ軸は一致します。
World SpaceのX軸の場合
- World SpaceのX軸はTangent Spaceのz軸です。
- World SpaceのY軸はTangent SpaceのX軸の逆です。
- World SpaceのZ軸はTangent SpaceのY軸の逆です。
World Spaceの-X軸の場合
- World Spaceのx軸はTangent SpaceのZ軸の逆です。
- World SpaceのY軸はTangent SpaceのX軸です。
- World SpaceのZ軸はTangent SpaceのY軸の逆です。
となりました。軸の向きを無視した場合
X軸はWorld SpaceのXYZ軸がTangent Space軸のZXYと一致します。
World SpaceのY軸の場合
- World Spaceのx軸はTangent SpaceのX軸です。
- World SpaceのY軸はTangent SpaceのZ軸です。
- World SpaceのZ軸はTangent SpaceのY軸の逆です。
World Spaceの-Y軸の場合
- World Spaceのx軸はTangent SpaceのX軸の逆です。
- World SpaceのY軸はTangent SpaceのZ軸の逆です。
- World SpaceのZ軸はTangent SpaceのY軸の逆です。
となりました。軸の向きを無視した場合
Y軸はWorld SpaceのXYZ軸がTangent Space軸のXZYと一致します。
つまり
X軸はWorld SpaceのXYZ軸がTangent Space軸のZXYと一致。
Y軸はWorld SpaceのXYZ軸がTangent Space軸のXZYと一致。
Z軸はWorld SpaceのXYZ軸とTangent SpaceのXYZ軸は一致となります。
これは「3.2 最初の変換を見る」の部分と同じです。
最初の部分の変換の意味が分かりました。
これはTangent SpaceからWorld Spaceへの変換じゃなくて、Tangent SpaceからWorld Spaceへ変換するための第一歩をやっていたんですね。
3.5 次の変換
以下の部分です。
これはTexture Sampleの値とVertex Normal WSの値を合わせる時の計算ですが
- X軸の計算ではX軸は掛ける、それ以外は足す。
- Y軸の計算ではY軸は掛ける、それ以外は足す。
- Z軸の計算ではZ軸は掛ける、それ以外は足す。
となっています。
この目的と意味を調べます。
この部分ですが何のためにしているのか全く分かりません。
試しに掛け算の部分を足し算に変えてみます。
一番単純なZ軸で試してみます。
こんな結果になりました。
こっちが元の状態です。
デコボコがはっきりしていますね。
因みに裏面です。
元の裏面です。
うーん。全く分かりません。
この計算を遡ると
と
を掛けているんです。
試しに以下の実装を組んでみました。
結果です。
Top Viewです。
Add ノードからMultiplyノードに変更しました。
変わりません。
Bottom Viewです。
Add ノードからMultiplyノードに変更しました。
あれ。全然変わりました。
上下で同じ色になりました。
今度はY軸で試してみます。
Top Viewです。
全部Addノードを使用しています。
Y軸だけMultiplyノードを使用します。
Y軸に沿って値が同じになりました。
Bottom Viewも確認します。
Y軸だけMultiplyノードを使用します。
はい。Y軸に沿って色が同じになりました。
X軸でも確認します。
X軸だけMultiplyノードを使用します。
はい。X軸に沿って色が同じになりました。
裏面も確認しましたが同じ結果になったので記録は省きます。
以下の計算は
Vertex Normal WSノードとAbsolute World Position ノードを合わせて使用する時、軸の+側と-側で同じ値を保つために行っているのかもしれません。
Projection全体の復習をしてVertex Normal WSノードとAbsolute World Position ノードの関係にもっと詳しくなってからもう一回考えます。
今回はこの部分の検証はここまでとします。
3.6 最後の変換部分
以下の部分の計算結果を
Texture Sampleの結果に掛けています。
この部分は先週のTutorialで正常のNormal MapとProjectionのNormal Mapの結果を比較してProjectionのNormal Mapの結果の間違いを直すために追加した部分です。
つまり何が目的なのかは既に分かっています。
ただし、先週は自分ではどの色が反転しているのかは見た目では分かりませんでした。
後、仮説でこの部分の実装はTangent Space からWorld Spaceへの変換ではなくProjectionの向きを直すために行っているのではないのか、と予測ましたが、それは間違いのようです。
まだTangent Space からWorld Spaceへの変換が完成していません。
<Z軸>
一番簡単なZ軸から見て行きます。
Xに以下にBの値を掛けています。
これをすると-zのxの値だけ反転するんでしたっけ?
先程のCubeにおけるTangent SpaceとWorld Spaceの比較を見ると
これで-Z軸のXの逆転が直るんですね。
因みに-Z軸のZの逆転は前の節の計算で直っているみたいです。
うーん。
合ってるかもしれません。
<Y軸>
Y軸はXに以下のGの値を掛けてます。
更にZ軸全体に-1を掛けています。
先程のZ軸の検証で使用した理論をここでも適用して考えてみます。
前の節の計算(Add, Multiply, Addの事)で-Y軸のYの逆は順になります。
ZはY軸でも-Y軸でも逆になっています。
これでZの逆は順になります。
最後のXは-Y軸だけ逆になっているので
と掛ける必要があります。
思いっきり掛けていました。
ああ。
もー分かりました。
いや大体分かりましたと言うべきですね。
<X軸>
X軸は以下の結果からどんな実装をすべきなのかを予測します。
-X軸のXの値が逆なのは、前節の(Multiply、Add、Add)で直っています。
X軸のYの値が逆で、-X軸のYの値が順なのはいつもの
を掛ければ直るんでしょうか?いつもと逆のPatternですね。
最後のZはX軸でも-X軸でも逆になっています。-1を掛けて直します。
先週の実装です。
Yの値には
を掛けていますね。これよく見るとXだけ-1を掛けていますね。
Xだけ逆になってるからこれそのまま使用出来るんですね。
Zには-1が掛けられています。予測通りでした。
3.7 Texture Sampleからの変換部分を検証して
始めた時は解ける気がしなくて、今週だけ挑戦して諦める予定でした。しかしそれなりかもしれませんが、何をやっているのか全部理解出来ました。
本来ならばここでもう一回簡潔にまとめ直すべきなんでしょうが、流石にそれは嫌なので別な事をします。
以下の仮説は間違っていて
この部分の計算はTangent SpaceからWorld Spaceの変換をしているだけと言う結論になりました。
その根拠だけここに書いておきます。
以下の図はNormal MapをそのままCubeに貼りつけたものです。
当然それぞれの面でWorld Spaceの座標軸と違う座標軸になっています。
これを各面毎にWorld Spaceの座標軸と同じになるような計算を追加しました。
これが先週やったTexture Sampleからの変換部分と完全に一致します。
つまり先週、訳わからずやっていたTexture Sampleからの変換部分は単にTangent SpaceからWorld Spaceの変換をしているだけだったんです。
以上です。
4.Prologueの作成
4.1 先週の絵の続き
神様です。
後は何を作成すべきが良く分かりません。
4.2 出来た部分だけ変えてみます。
出来た部分だけ変更して後何を作成する必要があるのか確認します。
お婆ちゃんの家と後ろの山、そして電車に乗っている背景が必要ですね。
電車の背景は要らないかもしれません。
お婆ちゃんの家と後ろの山を作成します。
後、セリフに関してですが、主人公の名前はないほうが良い気がします。
机に広がっている本が必要ですね。代わりにTabletでも良いかもしれません。
セリフはこれで良いと思います。
神社の絵と神社の周りの木が必要です。
下のセリフの部分に絵が被っています。泣き怒っている少年の絵と山の奥に佇んでいる神社の絵だけで良い気がします。
神社でお願いしている絵をもう一枚増やしても良いかもしれません。
ふて寝している主人公の絵が必要です。
後、ここで現れるお化けはアニメーションにして次々に表示させます。
神社と木の絵が必要です。
この絵を少しだけ明るくして神社でお願いしている絵にしてもいいかもしれません。
神社の絵が必要です。
ここで現れるお化け達はアニメーションにします。
ここは絵は良いですが、セリフを分ける必要があります。
銀河鉄道が来る前と来た後の2つの絵を作成してセリフを二つに分けます。
4.3 絵を作成する
もう絵は飽きたんですが、Prologueを完成させないと次の工程に入れないので続きをやります。
もう疲れました。
絵を描いていると時間を無駄にした感が半端ないです。
残りは来週やります。
Aminationと音楽の追加が必要です。
5.Open Worldの検証や他のMapの作成
5.1 Open Worldの検証や他のMapの作成のこれからの予定
先週、以下の勉強をこれからやっていくと書きました。
更に、先々週調べたWinter Forest Set、Stylized Desert EnvironmentそしてMultistory Dungeonsを使用して新しいMapの作成も行う必要があります。
新しいMapとして雪の積もった山、砂漠、そして迷宮の作成が必要だからです。
後、今まで勉強したLandscapeの作成方法とWorld Compositionの復習も必要です。
うーん。やる事多すぎる。
他のMapの作成とOpen Worldの検証を来週から分ける事にします。
<他のMapの作成>
Winter Forest Set、Stylized Desert EnvironmentそしてMultistory Dungeonsを使用して雪の積もった山、砂漠、そして迷宮を作成する。
勉強したLandscapeの作成方法とWorld Compositionの復習をする。
<Open Worldの検証>
World Machineの勉強をする。
公式のDocumentであるOpen World Tools [4] を勉強する。
Smart Poly氏のUnreal Engine 5 | Open World Tutorial Using World Partition [5]も勉強しておく。
今週はこれらを軽くやって見通しを建てます。
5.2 Winter Forest Set、Stylized Desert EnvironmentのLandscapeに使用しているMaterialを調べる
Winter Forest Set、Stylized Desert Environmentに付属のLandscape用のMaterialがあればそれを使用して直ぐに雪山や砂漠のLandscapeが作成出来ます。
2022-01-31のBlogを見たら、既にLandscape用のMaterialについても調べていました。
Winter Forest SetのLandscapeのMaterialに関してはLayer Blend ノードの使用方法が分からないので、このMaterialが使用出来るかどうか分からないみたいな事が書かれています。
うーん。
このノードの使用方法は一応、先週のBlogのSmart Poly氏のTutorialで勉強しました。更に前にMap1やLandscape4のLandscape用のMaterialを作成した時にも使用したはずです。
Layer Blend ノードはLandscape用のMaterialの作成では最も使用するノードの一つみたいです。
しっかり使用方法を勉強しておく必要がありますね。
Stylized Desert Environmentに付属のLandscape用のMaterialにはLayer Blend ノードは使用されていませんでした。
<Winter Forest SetのLandscape用のMaterial>
Winter Forest SetのLandscape用のMaterialをもう一度、見てみます。
Result ノードです。
このノードの設定方法が分からないですね。
Materialの設定が以下のようになっています。これと同じにしたら上記の設定になるんでしょうか?
試してみます。
以下のようになりました。
うーん。似てはいますが、World DisplacementとTessellation Multiplierが無いですね。
Winter Forest SetのLandscape用のMaterialではTessellation の設定が以下の様になっていました。
同じ設定にするとWorld DisplacementとTessellation Multiplierが使用可能になりました。
これらの設定の中でSubsurface Colorの使用方法が分かりません。
そう言えば氷とか皮膚などのMaterialの設定をするのにSubsurfaceを使用するんでした。
この辺の設定方法を勉強する必要があります。
後はLayer Blend ノードの使用方法を理解すればこのMaterialをそのまま雪山のLandscapeのMaterialとして使用出来ますね。
<Stylized Desert Environment>
一応、こっちのLandscape用のMaterialも見ておきます。
Result Nodeです。
Ambient Occlusionをセットしている以外は普通の設定です。
Base Colorです。
うは。
こっちの方が全然複雑な実装していました。
一個ずつ読んでいきます。
まずBase ColorのUVsに接続している部分です。
ここでもLandscape Coordsノードが使用されていますね。
Landscape Coordsノードについて調べます。
公式のDocumentであるLandscape Materials [6] には以下の説明がありました。
まあ。当然ですね。
後以下に示した設定の説明もあります。
この辺は使用する時に勉強し直します。
取りあえずはTexCoord[0]と同じ使い方と認識しておきます。
Base Colorの最初の部分です。
Base Color Tintで別な色のBase Colorを作成してLerpで混ぜています。混ぜる割合はBase Color Tint Amount Parameterで指定しています。
こういう混ぜ方をすると単にBase Colorに色を掛けた時とどう違うんでしょうか?
ちょっと試してみます。
これが
普通に色を掛けると
こうなります。
今度はLerpで試します。
結果です。
思ったより変わらないです。
(0.5,0,0)を掛けた場合と比較したらどうなんでしょうか?
結果です。
全然違いますね。
Lerpは色の白さ具合で混ぜるのでLerp ノードを使用した色の混合は他の方法では真似出来ませんね。
次にHueの値がいじれるような設定をしています。
こういう設定を作ってあるのはDesigner friendlyですね。
LerpにしろHueにしろDesignerが理解出来るParameterです。というかこれらの使用方法はDesignerの方が詳しいでしょう。
このような実装を作れるとDesignerとProgrammerのSynergyが発揮できるように成る訳ですね。
凄い勉強になります。
やっぱりProgrammerもMaterialの実装を作成する人はDesignの勉強は必要ですね。Designerの商売道具を理解してそれと同じ機能をMaterialに追加しておく。正しDesignerに触らせるのはそのMaterialのInstanceだけにしておく。
これでDesignerも自分の能力を最大に発揮出来るようになり最終製品の質もUserの満足いくものになるわけです。
次はDesaturationノードを使用しています。
これもDesignerの人にはうれしい機能でしょうね。
自分でMaterialを作成する時はBase ColorにはLerp、Hue、そしてDesaturationの機能を付加しておく事にします。
後は特に記録する内容は無かったです。
このMaterialをそのまま使用するかどうかですが、Layerが一個しかないので現時点では分かりません。
砂漠なんでLayerは要らないんでしょうか?
5.3 前に勉強したLandscapeの作成方法を復習する
Landscape4やMap1のLandscapeを作成した時の方法を復習します。
前回のLandscapeの勉強を何時したのか調べた所、2021-03-15のBlogから始まっていました。ほぼ去年の今頃ですね。
かなり長い期間、勉強しています。
最初の4,5回分の勉強を読みましたが元々のLevel Designの知識がないのでかなり難航しながら勉強しています。
これを読んでまとめるのはかなり大変ですね。
今週は全部読むだけにします。そして一週間熟成させて来週まとめます。
ここの勉強で曖昧な部分が沢山あったので今、Landscapeを自分で作成しようとするとあれ、どうやったっけとなってしまったんです。その辺をきっちりまとめ直します。AIの時のように後ですっかり忘れた時に見直す事が出来るようなしっかりしたTutorialを最終的には作成します。
2021-04-11のBlogまでずっとlandscapeの勉強をしていました。
Materialの知識が今ほどないのでかなり難航しながら解釈している部分もありますし、今、読むと全く忘れている箇所もあります。
新しいMapの作成はこれの復習がメインになるでしょう。
来週から頑張ります。
5.4 World Compositionの復習をします。
先週、Smart Poly氏のOpen Worldの作成方法を勉強しましたが、前にどうやってWorld Compositionを作成したのかを忘れてしまいました。ので復習します。その後でSmart Poly氏のやり方と比較して長所と短所をはっきりさせます。
2021-09-26のBlogで初めてWorld Compositionについて知って驚いています。
凄いですよね。
ここまでWorld Compositionを知らないでLandscapeを作成してたんですから。
Stream Levelの存在を知ってそこからLandscapeごとStream Levelに組み込もうとして出来なくて調べていたらWorld Compositionについて知りました。
これも今週は読むだけにします。来週、一つ一つまとめます。
全然関係ないですが2021-10-10 のBlogにTangent Spaceに関する記録がありました。
よく見たら、Ben Cloward先生のTutorial、View, World, Object, & Tangent Space - Shader Graph Basics - Episode 10 [7]を勉強していました。
これ見ると赤がNormal を表していますね。これは要確認が必要です。後でじっくりやります。
2021-11-22のBlogまで、なんやかんかWorld Compositionについてやっています。
軽く読んだだけですが、これ見ると先週勉強したSmart Poly氏のHow To Make A Massive Open World Map In Unreal Engine 4 [8] のやり方で統一した方が良い気がしますね。多分Smart Poly氏のやり方が、現状最も効率的なWorld Compositionの使用方法なんだと思います。
6.Open Worldの検証
やっぱり内容が全く違う事になりそうなのでOpen Worldの検証は別の章でやる事にしました。前章で述べたように
- World Machineの勉強をする。
- 公式のDocumentであるOpen World Tools [4] を勉強する。
- Smart Poly氏のUnreal Engine 5 | Open World Tutorial Using World Partition [5]も勉強しておく。
をやります。
6.1 World Machineを勉強する
World Machineの無料版をInstallします。
今週は、これだけ出来れば十分です。
ここからDownloadしました。
Free版は1025x1025より大きいAssetは作成出来ないそうです。
Installが終わったんでしょうか?
ちょっと手作り感を感じる作りですね。
これ動的にLinkしてるみたいですね。QtだからLicenseの関係でそうしてるんですかね。
これをクリックしてみます。
以下の画面が開きました。
合ってそうですね。
これで来週から勉強する事にします。
6.2 公式のDocumentであるOpen World Tools [4] を勉強する
今週はこのPageにあるTutorialの概要を把握します。
以下のTutorialが紹介されています。
更に、
と書かれています。
Procedural Foliage Toolって色々な個所で聞きます。これも勉強しておく事にしましょう。
ぱらっとOpen World Overviewを見た所、このSiteは全部、Procedural Foliage Toolの使い方を勉強するためのサイトのようです。
と書かれていました。
要するに、自分でFoliageを配置しないでPCが適当に配置場所を決定する訳です。
うーん。
でもこれLandscapeの木の配置で既に使用している技術かもしれません。
まあ勉強すれば分かる事です。
その具体的なやり方のTutorialがこの2つです。
はい。
これらの来週から勉強する事にします。
6.3 Smart Poly氏のUnreal Engine 5 | Open World Tutorial Using World Partition [5]を勉強する
まず軽く全部見ます。
あれ。このTutorial、見た記憶があります。はい。調べたら2021-10-10のBlogでしっかり勉強していました。と言うか、World Partitionを勉強した時のメインのTutorialの一つでした。このTutorialで勉強した事を完全に忘れてしまっていました。
実は今週は、これをしっかり勉強するつもりだったので一寸肩透かしを食らってしまいました。
6.4 World Machineを一寸だけ勉強します
Smart Poly氏のUnreal Engine 5 | Open World Tutorial Using World Partition [5]を勉強する必要が無くなったので急遽ですが、同じSmart Poly氏のHow To Make A Massive Open World Map In Unreal Engine 4 [8] のWorld Machineの部分をやってみます。
画面を開いたら
Advanced Perlinを選択して
以下に示したLayout Viewをクリックします。
以下の図が現れました。
Tutorialの画面と全然違います。
以下のボタンをクリックしろと言っています。
そんなボタンは見当たりません。
まさかこんなに早く詰まってしまうとは。
良く分かりませんがこのShapeというノードをAdvanced Perlinの代わりに使用すると
Tutorialと同じような事が出来ます。
それで思ったんですが、こっちの使い方を覚えた方が早く使用出来るようになりそうです。
これをパッと見て思うのは「UEのBPのようなVisual Scriptingでしょう。」です。
つまりここでWorld Machineは何かをProgrammingしている訳です。
UEのBPと同じ様に一個一個のNodeがC++のClass(むしろInstanceか)になっているはずです。
そして上記の解説を読むと、
- 緑の色で囲われている部分はTerrainを作成する部分をProgramしている。
- 青で囲われている部分はそれにTextureを貼る部分(UEならMaterialに当たる部分)をProgramしている。
- 最後の赤い部分が他のSoftwareで使用出来るようにExportする部分をProgramしている。
と考えらます。
となると先程のShapeノードの機能から考えて、多分ですがTutorialにあったAdvanced Perlinノードのこの機能は
Advanced Perlinノードから別なノードに移されたんでしょう。
ここにTutorialみたいなのを見つけました。
これ読んだら理解出来そうです。
今週のWorld Machineの勉強はここまでにします。
次の週までに、どうやってWorld Machineを勉強するのかを考えます。
7.Game Design:ポケモン+HxHの念能力( 戦闘システムの作成)
7.1 先週やった事の復習と今週やる事の確認
先週はPlayerの召喚したMonsterが対戦相手の召喚したMonsterを攻撃するSystemを作成しました。
しましたが、画面上における変化が全くない状態で作成したのでPlayerはGame内で何が起きているのか全く分かりません。
ので今週は
を実装します。
7.2 どのMonsterがどのMonsterを攻撃したのかが分かるようにする
まずは、Level BP内の
のMonster Attack関数の後にPrint Stringを追加して
以下の表示が出るようにしました。
Widget上に同様の情報が表示されるようにします。
コメント表示用のBoxを追加して
Level BPのMonster Attack関数の後のPrint Stringノードがあった所に以下の実装を追加します。
テストします。
以下の様になりました。
表示が速過ぎて文章が読み切れません。
読みましたボタンを追加します。
以下の実装を追加します。
Game ModeにEvent DispatcherであるEvent to Level Helper Player Monster Fightを作成します。
WidgetのボタンをClickした時にそのEvent Dispatcherを呼び出します。
Level上でGame ModeにEvent DispatcherであるEvent to Level Helper Player Monster Fightに
Event Player’s Monster’s Turn EndをBindさせます。
Event Player’s Monster’s Turn Endの実装は以下に示します。
これで「読みましたボタン」を押すまではWidgetは次のEventを発動させません。
テストしてみます。
この状態でずっと止まっています。
ボタンを押します。
次のTurnに移行しました。
ただし戦闘に勝利した時は「読みましたボタン。」が表示されないで次のPhaseに移行します。これは後で考えます。
後、バグを発見しました。
Monsterを選択しないで「決定ボタン」を押すとそのまま次のPhaseに移行してしまいます。
このバグを直しておきます。
応急処置としてMonsterを選択していない時は「決定ボタン」を押しても、次のPhaseに移行出来ないようにしました。
テストします。
決定ボタンを押しても次のPhaseに移行しません。
一体だけMonsterを選んだ状態や2体Monsterを選んだ状態で、決定ボタンを押しても次のPhaseには移行しません。
三体、Monsterを選んだ後で、決定ボタンを押すと次のPhaseに移行します。
出来ています。
7.3 全てのMonsterのHP/MHPなどのParameterがWidget上に表示されるようにする。UIの調査をする。
これの表示をWidget上に作成するのは簡単なんですが、どんなUIにすべきなのかについて少し調べます。
調べました。大体2パターンに分かれていました。
<Pattern 1>
四角タイプです。
四角の左上、もしくは上半分がそのMonsterのイラストです。そしてそのイラストの脇や上にそのMonsterの名前があります。後Monsterのタイプを表す記号が表示されていたりします。
下半分が、そのMonsterのParameterです。
数字とバーの両方で表示しています。
<Pattern 2>
長方形タイプです。
先程の正方形を上下で半分にして横に並べた感じです。
やっぱり戦闘に参加しているMonsterのイラストが表示されています。
あんまりゲームをしない私はRPGの戦闘画面がこうなっているって知らなくて結構、衝撃受けています。
私がアメリカの大学にいた時、Data、特に科学的なDataの可視化のための方法論を勉強する学問がありまして、3D Graphicsが専門のCSの学生は必ずそのクラスを取らなくてはいけないんですが、そのクラスで習った最も守らなければならない第一の原則が、無駄な情報は入れないです。
このMonsterのイラストはその全く無駄なものそのもので、更にHPの表示でも下にバーで表示しつつ、更に数字でも表示していると言うこれまた無駄な情報が入っています。
そのクラスでこのDesignをしたら、その場で教授に呼び出される位の駄目なDesignなんです。
でもこれが市場の競争で勝ち残って来た資本主義的には正しいDesignなんですね。
7.4 全てのMonsterのHP/MHPなどのParameterがWidget上に表示されるようにする。UIを作成する
前節の結果を考慮して以下のデザインに決定しました。
Typeを表示する箇所がないのでその点は後で考えます。
以下の様な表示になります。
7.5 全てのMonsterのHP/MHPなどのParameterがWidget上に表示されるようにする。UIを実装する
先に結果を示します。
こんな結果になりました。
実装方法の解説です。
MonsterBPの変数を増やしてここで表示する全ての情報をMonsterBPが持っているようにしました。
更にW_Monster Parameter内にMonsterBPを保持する新しい変数を追加します。
W_Monster Parameterの値はこのMonsterBPからセットするようにします。
後は、W_Monster ParameterにMonster BPをパスするだけです。
Level BP内で新しい関数を作成しその関数にPlayer Attack Widgetをパスします。
その関数内でW_Monster ParameterにMonster BPをパスしました。
出来れば、Player Attack Widgetを初期化する時にそれぞれのW_Monster ParameterにそれぞれのMonster BPをセットしたかったんですが、それをするためにはPlayer Attack Widgetにも6つのMonster BPをパスする必要があり止めました。
このCombat Systemは動けば良いPrototypeなのであんまり深くは考えないでどんどん作成していきます。
7.6 タイプの表示を追加する
まずグー、チョキ、パーのImageを作成しました。
32x32なので絵が変ですが区別はつくはずです。
Monster ParameterにMonster Typeを追加します。
以下の実装でMonster TypeにジャンケンのImageを追加します。
結果です。
ジャンケンのグー、チョキ、パーの区別はつきますね。
7.7 Freeの2Dイメージを調査する
UIに使用出来るFreeのImageを調べます。
Libraryを見たら以下の2DのImageがありました。
これらから見て行きます。
<Craft Resources Icons>
Textureが入っていました。以下にその内の幾つかを示します。
これはそのまま利用できます。
WidgetのCommentを表すBoxのBackground Imageが欲しかったんですがそれはないですね。
<Pro Icon Pack>
これはTextureでそのまま描かれているのではなく、TextureのImageを合成して作成しているようです。
今、使用したいImageではないですね。
<The Vagrant: Background Construction Pack 01 >
これPack 02 をInstallしようとしたら01と同じと表示されたんですが、同じじゃないはずです。どっちかしかInstall出来ませんでした。
どう見れば良いのか分かりません。
Mapを開いたら以下の様な表示がされました。
うーん。よく分からない。
<Marketで探す>
MarketでGUIとか2D Assetとかで検索しましたが望んでいる絵は無かったです。
<ネットで探す>
ネットで適当にサーチしていたら
Game dev marketと言うサイトで
こんなのがありました。
登録しないともらえないのか。
少し考えてみます。
8.UE5:Naniteの勉強
Naniteの勉強はこれ以上勉強する教材見つからないので一端終わりにします。Lumenの勉強を来週からします。
9.Blenderの勉強
今週も、Imphenzia氏のLearn Low Poly Modeling in Blender 2.9 / 2.8 [9]をやっていきます。
9.1 先週の復習
先週何を勉強したのか全く覚えていません。復習から始めます。
<原点を中心にして回転>
これは覚えています。MouseのWheelを押してMouseを動かせば良いんです。
<Panning>
画面をそのまま左右上下に移動させる方法です。
全くやり方を覚えていませんでした。
Shift + MouseのWheelを押してMouseを動かす。で出来ました。
<Zoom in Zoom Out>
MouseのWheelを動かす。と出来ます。これはUEでも一緒です。
<上面図などへの変換>
Number Keyを押すとなります。
<以下の部分の名称>
Properties Areaです。
Spanner の部分しか使用しないそうです。
<以下のBoxの開き方>
KeyboardのNを押すだけです。
完全に忘れていました。
<Mouse のLeft ButtonはObjectの選択に使用します。それではRight Buttonは何に使用しますか?>
何にも使用しないそうです。
<選択したObjectを消す方法>
Delete Keyで消えます。
これはどの3D softでも同じでしょうね。
<以下の画面を表示する方法>
MenuバーのShadingを選択します。
<UV Editing画面の開き方>
MenuバーのUV Editingを選択します。
<View port Shadingの表示の仕方>
これは難しかったヤツです。
UV Editing画面のTool barにある以下の一群の赤線で囲った部分をクリックすると表示されます。
しかしUV Editing画面を開いた状態では以下に示した様に上記の一群が表示されていません。
これらの一群を表示するためには、以下の様になってる画面を
以下の様に右側だけ大きくする必要があります。
<以下の様な画面を作成する>
勿論、全く覚えていません。
まず、Imphenzia氏のTutorialからDownloadしたTextureをそのままDrag and Dropすると以下に示した茶色のNodeが表示されます。
そのNodeのOutputであるColorをBase Colorに繋げます。
すると以下の様なTextureがboxに貼られます。
今度はTextureを表す茶色のNodeのLinearをClosetに変換します。
するとBoxのTextureが以下の様に変化します。
この状態でUV Editingを開くと以下のような図が表示されます。
<Textureの選択面を点に変更する>
以下に示した選択面を
以下の様に変更します。
これを先週勉強した事は覚えていますが、やり方は全く覚えていません。復習します。
まずKeyboardのAを押して全選択します。全部を選択すると以下の様になります。
ここでScalingを変更するためにKeyboardのSを押します。
以下に示した様な矢印が表示されます。
この矢印が表示された状態で0を押すと
になります。
このやり方なんて全く覚えていませんでした。
でもこのやり方結構重要な気がします。
この部分は何回も復習する必要がありそうです。
<この点を自由に動かすには?>
KeyboardのGを押すと自由に動くようになります。
<Boxの色の表示が消えてしまった>
今、気が付いたんですがBoxに色が付いていません。直します。
Viewport ShadingのColorの選択をTextureに変更します。
これで色が表示されます。
<選択した面の色だけ変更する>
何故かこれだけはやり方を覚えていました。
Tool barにある以下の表示から面を選択します。
これで面が選択出来るようになります。
面を選択したら左の画面のOrangeの点をKeyboardのGを押して移動します。
紫色に移動しました。
以下の様になりました。
疲れた。
復習しているだけで結構疲れてしまいました。
そしたら、先週も全く同じ所で疲れた止めると言っていました。
時間にしたら先週の20%も勉強していません。でも同じ個所で疲れたと言っています。
この部分の勉強が何か強烈な負荷を精神に掛けているんでしょうか?
<Shinny Viewport Setting>
Shinney Viewport Settingを行います。
勿論、やり方は全く覚えていません。
以下のViewport ShadingのShadowにCheckを入れて
更にCavityにもCheckを入れます。その後でCavityのタイプをBothに変更します。
忘れていました。
以下の設定も必要です。
Edgeの周りが僅かに光って見えます。
こういうカッコイイ見せ方はこれから勉強する必要がありますね。
<面の向きをチェックする>
面には向きがあります。Normalがある方が表ですね。この面の向きはどうやってCheckするのかです。
はい。
全く覚えていません。
先週のBlogを読み直します。
Viewport ShadingのBackface Cullingにチェックを入れるだけでした。
要するにBlenderのDefaultの設定はUEのMaterialのDefaultの設定とは逆なんです。
UEのMaterialはTwo SideにCheckを入れないと裏面から見た時は透明になります。BlenderはBackface CullingにCheckを入れると裏面が透明になるんです。
<面を裏返しにする方法>
全く覚えていないので、答えを見てやります。
F3を押して、Flip Normalとタイプするそうです。
出て来たImageだとNormal Flipですね。
何にせよ出来ました。
<Object ModeとEdit Modeの切り替え>
以下の部分でします。
Object ModeはObjectを動かすModeでEdit ModeがそのObjectを構成するVerticesを動かすModeです。
<Vertex、Edge、そしてFaceの選択>
以下の3つの選択をKeyboardからする方法があります。それはどうやるんでしょうか?
Hot Keyの123で切り替えられます。
<以下の様に選択した面を自由に動かす方法>
面を選択した後、Gを押すとその面を自由に動かせます。
<選択した面をXYZ軸に沿って動かす方法>
以下の矢印を表示させて、選択した面をXYZ軸に沿って動かします。
覚えています。
これ、先週一回目は出来たのに次から出来なくなったやつです。
Shift + SpaceでGを選択だそうです。
出来ました。
出来ましたが、Gは押せなかったです。代わりに以下のBoxのMoveをCursorで選択する事で出来ました。
<上記の矢印をDefaultで表示する方法>
以下の図で示したDefaultのMoveにチェックを入れると出来るそうです。
<今度はVertexを動かす方法です>
Vertexを選択してGを押すと以下に示した様に自由に動かせます。
別にGを押さなくても表示されている矢印を選択することでXYZ軸上に自由に動かせますね。
GGを押すとEdge上だけを自由に移動出来るようになります。
このGGの機能は覚えておく必要がありますね。
<Scalingについて>
これはKeyboardのS Keyでしょう。
S Keyで合っていましたが対象となるVerticesを選択しておかないと駄目でした。
後、重要な事はCursorの位置を対象となるFacesから遠くにおくとやり易いです。
<Pivot Pointの表示方法について>
Pivot Pointって何だっけと思ったら以下の奴でした。
これはKeyboardのPeriod Keyを押すと表示されます。
先週のBlogではこの後に、Individual Originsを選択した場合としない場合の違いを正面と裏面の2面を選択した場合のScalingを使用して解説しています。
やってみます。
<Individual Originsを選択した場合としない場合の違いをCubeの正面と裏面の2面を選択したScalingを用いて説明せよ。>
単にCubeの正面と裏面の2面を選択してScalingを行った場合は以下に示した様に、Cubeのサイズが変わるだけです。
Individual Originsを選択した場合は選択した2面のサイズのみ変化します。
<Extrudeのやり方>
こんなのKeyboardのE Keyだろ!って押したら出来ました。
SとEの組み合わせで以下の3Dモデルを作成しました。
9.2 Imphenzia氏のLearn Low Poly Modeling in Blender 2.9 / 2.8 [9]の続きをやる
<Extrudeの続き>
下図に示したように表のニ面を選択しています。
この二つの裏面も選択してあります。
この状態でExtrudeを行うと以下に示したようになります。
Extrudeしてくれません。
今度はAlt+Eを押して以下のBoxを表示させExtrude Faces Along Normalsを選択します。
すると以下の様に全部の面がそれぞれのNormalに沿ってExtrudeします。
今度はExtrude Individual Facesを選択します。
すると
以下の様にそれぞれのFaceが独立してExtrudeします。
Tutorialでは述べていませんが、私のはNormalが裏返って面が透明になっています。
F3、Normal Flipで面の向きを直して見ました。
Sを押してサイズを変更してみました。
今度はPivot PointのIndividual Originsを選択してからScalingを行いました。
うーん。
あんまり違いが分かりません。
<もう一つのExtrudeする方法>
Ctrlを押したままMouseのRight ButtonでExtrudeが出来るそうです。
出来ない。
と思ったらCtrl を押したままMouse のRight ButtonをClickするとCursorのある位置までExtrudeします。
ずっとDragしてました。
この方法は以下に示した様にOrthogonal なViewで使用すると以下に示した様な立体が作成出来るそうです。
ふーん。です。
サソリの尻尾でも作るときに利用します。
<回転させる>
Rを押して回転させます。
特にコメントはないです。
Faceを回転させるんじゃなくて画面を回転させる時に、UEの癖でAlt + Mouse のLeft Buttonを押してしまいます。MouseのWheel を押せば動くのは分かっているんですが反射で押してしまい凄くイライラします。
<複数の面を選択した状態で回転させる>
Blenderを間違えて消してしまったので新しいModelを作成しました。
4つの面を選択した状態でRで回転してみます。
こんな回転になりました。
これは知らんでも良さそうですね。
<XYZ軸に対して回転させる方法>
X軸、Y軸、Z軸に対して回転させる方法です。
Rを押した後にKeyboardのX,Y,Zのどれかを押します。以下の図はZを押した場合です。
Z軸に対して回転しています。
その後に数字を打ち込むとその数字の角度だけ回転します。
以下の図はR、Z、45を打ち込みました。
45度、Z軸に対して回転しています。
Imphenzia氏はイギリス英語ですが、本当にZの事をゼットって言っています。びっくりしました。ほとんど初めて聞きました。zの事をゼットって言うのを。
<Inset>
Insetってどんな機能なのかと思ったら以下に示した様に面の中に小さな面を作成する機能でした。
Keyboard のI Keyを押すと出来ます。
以下に示した様な形状を作成するのに使用出来るそうです。
分かりました。
複数の面を選択した状態でInsetを行うと以下に示したように一つの繋がった面としてInsetが行われます。
以下の図は複数の面を選択した状態でInsetを行い、その後でExtrudeで面を凹ませています。
Iを2回押すと全ての面がバラバラの状態でInsetが行われます。
以下の図は複数の面を選択した状態でIを2回押してInsetを行い、その後でExtrudeで面を凹ませています。
<新しいObjectを配置する>
Shift + Aで
が表示されるのでMeshからCubeを選択します。
ここまで習った技術で何か作ってみました。
神社にある灯籠風のObjectです。
くり抜きする技術が有ったらもっと綺麗に出来たはずです。
後四角だけでなく多角形のModelから作成出来たら下の土台がもっと綺麗になりました。
時間が無くなってしまったので今週はこれまでにします。
10.まとめと感想
来週は、Prologueを完成させてPRGのProjectに統合します。早くこのRPGのProjectを終わりにして次にProjectを始めたいです。
11.参照(Reference)
[1] CGHOW. (2021, December 31). Happy New Year ! | Download Free UE4 Niagara Project [Video]. YouTube. https://www.youtube.com/watch?v=n-GuGpByALQ
[2] Andurlekar, H. [Hrishikesh Andurlekar]. (2020, May 18). UE4 4.25 Niagara Event Handler Simplest Example [Video]. YouTube. https://www.youtube.com/watch?v=wJ5o8mxeyXY
[3] 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=31
[4] Epic Games. (n.d.-b). Open World Tools. Unreal Engine Documentation. Retrieved February 13, 2022, from https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/OpenWorldTools/
[5] Smart Poly. (2021, June 3). Unreal Engine 5 | Open World Tutorial Using World Partition [Video]. YouTube. https://www.youtube.com/watch?v=efN4bGbzr78
[6] Epic Games. (n.d.-a). Landscape Materials. Unreal Engine Documentation. Retrieved February 13, 2022, from https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/Landscape/Materials/
[7] Cloward, B. [Ben Cloward]. (2021, August 12). View, World, Object, & Tangent Space - Shader Graph Basics - Episode 10 [Video]. YouTube. https://www.youtube.com/watch?v=E6Srr-HaicI&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=11
[8] 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
[9] Imphenzia. (2020, June 25). Learn Low Poly Modeling in Blender 2.9 / 2.8 [Video]. YouTube. https://www.youtube.com/watch?v=1jHUY3qoBu8