<前文>
<Loop中に動的に変数の名前を決定する方法は?>
これRedditに載っていたジョークなんですが、結構考えさせられたのでここに書いておきます。
まず動的に変数の名前を決定する方法自体、私は知らないです。この時点でかなりビビってこの話を読んでいました。
Computer Scienceにおける動的、つまりDynamicの正確な定義は、Runtime中にと言う意味だそうです。Runtime中に変数の値を決めるのなら分かりますが変数の名前なんか決められるんでしょうか?
更に、Loop中にと限定しています。と言う事は普通のProgrammerはLoop中でない場合は、Runtime中に変数の名前を決定する方法は常識として知っているって事になります。これは焦りました。
それでしっかり読んだんですが、この質問の解答は「配列(Array)を使う。」だそうです。
「何。それ」と言うか、「何で?」と思ったんですが、よく考えたら、配列(Array)って変数の値を追加する時にその変数の名前もその時に自動的に決定している訳です。
この質問は動的に変数の名前を自由に決定する方法とは言っていませんし、変数の名前を決定する時にその変数の型も指定出来るようにしろとも言っていません。
騙されたんだと気が付きましたが、不思議と怒る気にはなりませんでした。
<Gameの目的について>
私はGameはあんまりと言うかほとんどしないので、Gameが趣味の人がどうしてGameをするのかが良く分からなかったんですが、最近分かって来ました。
Gameの目的ってストレスの発散なんです。
このストレスというモノは実態がないので数値化して表す事が出来ないですが、確実に存在して人の行動をかなりNegativeな方向に支配しています。
私はひそかにこのストレスはEntropyの事なんじゃないのかと思っているんですが、証明する方法は思いつかないです。
それは兎も角として、ゲームの話に戻りますが、優れたゲーム、売れるGameは、故にストレスが発散出来るゲームになるんです。
このストレス発散について研究したら、面白いGameを作成するためのヒントがあるかもしれません。
<NFTと所有権>
前にNFTが著作者の所有権を守らないで、著作者から盗んでNFTに登録した泥棒にその盗作の所有権を認める、とんでもない結果になりそうと書きましたが、アメリカでは既にその被害が出始めているようです。自分が撮った写真をTwitterに載せたら、NFTの団体からその写真の著作権は我々にあるので消してほしいと要請され、消されてしまった話をいましがた聞きました。
NFTは失敗に終わるでしょうね。
<UkraineとRussia>
今のアメリカのz世代は今までのアメリカ人とは違い非常にアジアに詳しいです。その彼等の間でこういうジョークがあります。
中国人と韓国人が一緒になると日本人の悪口ばかり言う。中国人と日本人が一緒になると韓国人の悪口ばかり言う。韓国人と日本人が一緒になると中国人の悪口ばかり言う。
このジョークはアメリカ人に対して、アジア人が他のアジア人の悪口を言っていても兄弟喧嘩みたいなもんだから、その話をまともに聞くな。という警告でもあります。
実際、アメリカでアジア人が人種差別主義者から殴られたりしたら、直ぐに中国人も韓国人も日本人も突然和解して一緒に戦います。
私はアメリカの大学の研究室にいた時に上司がユダヤ系のウクライナ人だったことがあり、暇な時にその人から色々ウクライナやロシアの話を聞かされていたので、普通の日本人よりはこの辺の事情に詳しいですが、ロシア人とウクライナ人と東方ユダヤ人って日本人からみたら全く区別出来ません。
今のUkraineとRussiaと更に東方ユダヤ人を巻き込んでの喧嘩は、この中国人と韓国人と日本人の喧嘩と同じなんです。兄弟喧嘩なんですよ。どんな結果になろうと日本人が首を突っ込むと今度はこの三者が組んで日本を叩きにきます。
日本はこの問題に対しては「見ざる聞かざる言わざる。」で対応するのが一番です。
それでは今週の勉強を始めます。
<本文>
1.今週の予定
今週も先週と同じ内容でやっていきます。
- Niagara: Particle Attribute Readerの検証
- Material :Projectionの勉強の復習
- Prologueの作成
- Open Worldの検証
- 他のMapの作成
- Game Design:ポケモン+HxHの念能力( 戦闘システムの作成)
- UE5:Lumenの勉強
- Blenderの勉強
2.Niagara: Particle Attribute Readerの検証
今週はParticle Attribute Readerの勉強をします。
2.1 Particle Attribute ReaderのTutorialを探す
ほとんどないです。
CGHOW氏の動画が何本かと
先々週、参考にした【UE4.26】Niagara Advanced 解説基礎編~Particle Attribute Reader~ [1] とContent ExamplesのAdvanced Niagaraにある以下の3つの例です。
こっちは4つあるんですが残りの一個はどこに展示してるんでしょうか?
2.2 Particle Attribute Reader in UE4 Niagara Tutorial | Download Project Files [2] を軽く見る
途中まで見ましたが大体、Particle Attribute Readerの使用方法が分かりました。
このTutorialで勉強する事にします。
Particle Attribute Readerって文字通り「ParticleのAttributeを読む。」つまりParticleが持っているPropertyを読み込む事が出来る変数みたいです。
変数なのでScratch PadからParticle Attribute Reader にAccessして、更にAccessしたParticle Attribute Readerから必要な属性、位置などを読み取ります。その情報は他のModule内で使用出来るように新しい変数(input?)を作成してその変数(Input)にPassします。
これだけ理解出来れば実装出来そうです。
2.3 Particle Attribute Reader in UE4 Niagara Tutorial | Download Project Files [2] を勉強する
Fountain Templateから以下のEffectを作成しました。
今回はEffectの作成が目的ではないのでこのEffectの作成方法は記録しません。
このEffectは既に素晴らしいですが、以下に示した様に、このEffectを並べると同じEffectを繰り返してるだけと直ぐに分かってしまいます。
この理由は、このEffectのForceの中心がRandomに生成されていないからです。
以下に示した新たなEmitterを追加して
このRandom に生成された赤い点を中心に渦を作成するように改良します。
最初に原理を理解するために以下の示した様な赤い点一個に対して渦の中心を作成するようにします。
やっとここでParticle Attribute Readerの出番です。
この赤い点の位置情報をParticle Attribute Readerで獲得して、その情報を渦を作成しているModuleにパスします。
Particle Update SectionにNew Scratch Pad Moduleを追加します。
中を開き、Map Get Node内からNew Particle Attribute Readerを追加します。
次にGet Vector by Index ノードで赤い点のPositionを引き出します。
赤い点は常に一個しか生成されていないのでIndex Numberを0にすれば赤い点にAccess出来ます。
今度はその値を他のModuleでも使用出来るように、新しい変数(input?) を作成します。
Map Set Node内にName SpaceがParticle、typeがVector、の変数を作成しました。名前はNewPositionとしました。
NewPositionに先程の赤い点の位置情報をAssignしました。
これで完成とApply ボタンを押したらErrorが表示されました。
Emitter Nameに獲得するEmitterの名前を追加します。
Errorが消えました。
このNew Positionの値をPoint Attraction Force ModuleとVortex Force Moduleにパスします。
まずPoint Attraction Force ModuleのAttractor Position OffsetにNew Positionをセットします。
次にVortex Force ModuleのVortex OriginにもこのNew Positionをセットします。
以下のような結果になります。
渦の中心が赤い点になっています。
今度は赤い点を2個に増やします。
Emitter Update SectionのSpawn Rate Moduleの
Spawn Rateの値を2.0にします。
これで2個のParticleが生成されるようになりましたが。
渦の中心は最初の赤い点のみを追いかけています。
その理由は先程作成したScratch Module内でParticle Index 0の値しか収得していないからです。
ここからTutorial自体が少し迷走し始めます。
結果的には複数の赤い点を追いかけるParticleが完成するんですが、そのやり方が一寸納得いかない部分もあります。
まずTutorialの通りにやります。
その後でそのやり方を検証します。
最初はExecution Indexを使用します。
これTutorialの場合は何も変化しません。
しかし私の場合は
明らかに赤い点を渦が追いかけています。
これは後で検討します。
もう一つの疑問が赤い点を作成するEmitterのEmitter Settings SectionのEmitter Properties Moduleの
Requires Persistent IDsをどうしているのかについて何のコメントもしていない事です。
これセットしてこのIDの値から紐付けしたら上手く行く気がします。
これも後で検討します。
取りあえずはTutorial通りにやります。
前にこのやり方でPositionを追った時は出来たので、ForceにPositionの位置を使用してるからではないか?と推測しています。そしてこの場合でも出来るようにするには
- Particleを初期化する
- 初期化したParticleからIDを取得
- 取得したIDをGet Positionノードにパスする
と説明しています。
うーん。私的にはその前にRequires Persistent IDsを使用する方法を検討してほしいですが、Requires Persistent IDsについてはこのTutorialでは全く出て来ません。
Particle Spawn Sectionに新しいScratch Moduleを追加します。
更に中で以下の実装を用いて生成した赤い点の数を求めます。
1を引くのは赤い点の数え方は0から始まるからです。
次にMap Set ノードにParticle Name SpaceのIDをセットします。
ここまではまあ、分かるんですが、この後、このIDの名前をNew IDに変更してしまいます。
この意味が分かりません。
このParticle IDは元々ある変数で、それぞれのParticleのIDを管理してる変数であるはずです。
その名前を変更するとどうなるんですしょう。
Particle IDとは別な変数が出来るんでしょうか?
もしくはParticle IDの名前が変わるんでしょうか?
Particle ID 変数はここだけじゃなくて色々な個所で呼び出されると思うんですが、その時にこの変数の名前が変更されていたらどうなるんでしょう。変更された名前が呼び出されるんでしょうか?
全くどうなるのか分かりません。
もし名前を変更する事で、全く新しい変数になるのなら最初から新しい変数として作成すべきだと思います。
Particle IDのままなら名前を変更する意味が無い気がします。名前を変更すると他でParticle IDを呼び出してる箇所に何らかの悪影響が出る気がします。
以上のような事を思いましたがここではTutorialと同じ様にやります。
NewIDに名前を変更しました。
そして以下の実装を作成しました。
これだと、作成された赤い点の中の一つを選択してその点のIDをパスしている事になります。
それが目的なんでしょうか?
色々な疑問が生じますがこのまま進めます。
最初に作成したScratch Moduleに戻り、Map GetノードにParticle IDを追加します。
このIDの名前をNew IDに変更し以下の実装を作成しました。
渦が全く赤い点を追わなくなってしまいました。
それでTutorialではParticle IDを使用したからこうなったので、Particle IDの代わりにNew Niagara IDを使用します。
この後も色々しますが、最後にSpawn rate ModuleをSpawn Burst Instantaneous Moduleに変更すると上手く行くようになります。
今週はTutorialをそのままやると決めたので全く同じ様にやります。
名前をNewIDに変更してName SpaceをLocalからParticleに変更します。
こっちのScratch ModuleでもParticle NewIDを外してNew Niagara IDを代わりに追加して
名前をNew IDに変更しました。
この元からある変数の名前を変更するのはどういう意味があるのが今一分かりません。
ひょっとすると変数のTypeを同じにするためにやっているのかもしれません。
それなら納得出来ますね。
しかし結果は変わりません。
今度はEmitter Update SectionにParameter Attribute Readerを読むためのReaderを追加します。
名前はParに変更しました。
TutorialだとPARなんですが、PARと入力してもParになってしまいます。
そしてScratch ModuleのNew Particle Attribute Readerの所に
Parをセットします。
この辺は結果的には問題を解決に導かなかったですが、勉強になります。
もう一個のScratch Moduleも同様に設定を直しました。
しかし結果は変わりません。
CGHOW氏、めっちゃ考えています。
そして渦を作成してるEmitterのSpriteがSpawn Rateだと常にSpriteがSpawn されているから赤い点の情報が得られないとの結論に至ります。
そしてSpawn Burst Instantaneous Moduleに変更します。
その結果です。
うーん。赤い点に向かって渦撒く時と巻かない時がありますね。
今度は赤い点を五個に増やしました。
全く渦が動かなくなってしまいました。
あれ。
Tutorialの方は渦がそれぞれの赤い点に向かって動いています。
よく見るとTutorialのは赤い点がずっと表示されています。
あれ?
赤い点の方もSpawn Burst Instantaneous ModuleでSpriteを生成させています。
直しました。
何か出来たり出来なかったりしています。
今度は一番最初に作成した赤い点がGrid状にならんでいるEmitterと交換します。
渦のEmitterのSet Emitter Par ModuleのEmitter nameをPointsに変更します。
更にEmitter PointsのParticle Update SectionのParticle State Moduleの
Kill Particle When Lifetimeのチェックを外し
Emitter Update SectionのEmitter State Moduleの
Loop BehaviorをOnceに変更します。
この後、Tutorialのやり方をそのまま真似ましたが、Tutorialのように
それぞれの赤い点に向かって渦が発生するような事になりませんでした。
第一、以下の実装で赤い点の内からRandomに一点選んでその位置を指定しているはずなのに
なんで全部の赤い点に向かって渦が動くのか?
ちょっと良く分からないです。
一端このTutorialは中止にします。
2.4 Content Examplesのサンプルを見てみる
<2.1 Particle Attribute Reader>
まず2.1 Particle Attribute Readerを見てみます。
Niagara Systemを開いて見ます。
こっちは普通のEmitterですね。
こっちが先のEmitterのParticle AttributeのDataを読んで発動するEmitterです。
こっちを見て行きます。
Emitter Spawn SectionにParticle Attribute Readerをセットしていますね。
ここで読むEmitterの名前を指定しています。
Particle Update SectionのRead Color From Emitter ModuleがScratch Moduleから作成されたModuleです。
此処で先程作成した変数、Attribute Readerをセットしています。
直接ここでParticle Attribute Readerをセットしても変わらない気がします。
実装を見て行きます。
はい。Particle Indexが0の場合です。
これは先程のParticle Attribute Reader in UE4 Niagara Tutorial | Download Project Files [2]で出来た部分と同じやり方です。
後は特に記述する事はないです。
<2.2 Follow The Leader 1.0 >
次はこれを見て行きます。
これ赤い球それぞれに沢山の緑の小さい球がくっついていますね。
仕組みとしてはParticle Attribute Reader in UE4 Niagara Tutorial | Download Project Files [2]で出来なかった部分と一緒です。
このEmitterが赤い球を作成しています。
そしてこっちのEmitterがその赤い球に群がる沢山の緑の玉を作成しています。
このEmitterを見て行きます。
まずEmitter Spawn SectionにAttribute Readerがセットされていました。
これはまあ理解出来ます。
設定も普通です。
Emitter UpdateでParticle の生成方法を指定していますが、Spawn Burst Instantaneous Moduleが使用されています。
Particle Spawn SectionにParticle Attribute Readerを使用するScratch Moduleが有りました。
中身を見てみます。
あれ、この部分でさっきのTutorialと全く同じ組み方ですね。
うーん。
これでそれぞれの赤い球にくっついていく事になるんでしょうか?
良く分かりません。
次のノードも全く同じですね。
うーん。この説明が正しくなるためには赤い球を作成するEmitterのPersistentにチェック入れないと駄目なんじゃないの?と思いました。
チェックしてみます。
入っていました。
前節の「2.1 Particle Attribute Reader」のEmitterには入っていません。
と言う事はやっぱりEmitterのPersistentにチェック入れる必要があるんですよ。
この実装でIDを収得するには。
こっちのEmitterには更にParticle Update SectionにParticle Attribute Readerを使用するUpdate Followers Moduleが作成されていました。
以下の部分ですがここは納得です。
別に問題ないです。
次のこの部分で移動距離と方向を計算しています。
その次の部分ではVelocityを計算しています。
細かい計算は後で考えます。
2.5 もう一回、Particle Attribute Reader in UE4 Niagara Tutorial | Download Project Files [2]の出来なかった部分をやる
まず赤い球のEmitterのRequires Persistent IDsのチェックは既に入っていました。
これはCalculate Random Range Integer Module を使用した時に発生したErrorのFixを押した時に自動で直されたようです。
ずっとこれを直せば複数のObject用のParticle Attribute Readerは正しく動くと思っていたのに既に直っていたとは。
予測が外れました。
この後、別な問題を発見し、それを直すと100%ではないですがTutorial通りに動くようになりました。
それは何とSubtract ノードです。
以下のSubtractをTutorialやContent Examplesの「2.2 Follow The Leader 1.0」と全く同じSubtractノードにします。
以下の様になりました。
何時もなる訳じゃないですが、それぞれの赤玉に渦が付いていくようになりました。
うーん。
Particle Attribute Readerにはまだまだ分からない部分があります。
今週はここまでにして来週またやる事にします。
3.Material:Projectionの勉強の復習
今週からは先週まで勉強して来たProjectionの復習とまとめを行います。
3.1 Tangent Spaceの座標軸について
先週のBlogでUEのTangent Spaceの座標軸は以下のように設定されていると推測しました。
その推測に基づいてTangent SpaceからWorld Spaceの変換を行うと、Triplanar Projection Normal Maps - Shader Graph Basics - Episode 30 [2] の実装方法について完全に理論的に説明出来ました。
ので上記のTangent Spaceの座標軸は合っていると確信していますが、以下の記録を見つけました。
これだとTangent SpaceはX軸がNormal を指しています。しかもこのScreenshot、Ben Cloward先生のTutorial、View, World, Object, & Tangent Space - Shader Graph Basics - Episode 10 [3]から取って来ているみたいです。これは要確認が必要です。
まずこれをやります。
3.2 Ben Cloward先生のTutorial、View, World, Object, & Tangent Space - Shader Graph Basics - Episode 10 [3]を見直す
このTutorialの4:30ぐらいからTangent Spaceについての説明が始まります。
内容自体は、先週のBlogにまとめた定義と同じでした。
正し、その解説で使用したXYZ軸は以下に示した様にX軸がNormal Vectorを表しています。
最後まで聞きましたが、これがUEのTangent Spaceを示してるとは言っていません。(UEのTangent SpaceのXYZ軸がこれでないとも言っていませんが)
他の資料でTangent Spaceについて述べているのも見つけました。
茄子 著の「Unreal Engine 4マテリアルデザイン入門」[5] のタンジェント空間の説明では「タンジェント空間のZ軸は法線と方向が一致します。」と書かれていました。これは私が先週採用したTangent SpaceのZの座標軸と一致します。
ここに書かれているTangent空間がないとNormal Mapが展開出来ない、それは接線方向(Tangent)が決められないから。という解説は非常に納得しました。
言われてみれば三次元における曲面上の一点の傾きはそのNormal Vectorに対して垂直ならば、あらゆる向きに対してとれる訳でどこかで定義する必要があります。
これだけTangent Spaceに対して説得力ある説明をしている本が、UEのTangent Spaceでは「タンジェント空間のZ軸は法線と方向が一致します。」と言っていて、それは先週の私のUEにおけるTangent Spaceの座標軸の定義の推測と一致していますので、これで正しいとします。
3.3 Using Position Data - Shader Graph Basics - Episode 26 [6]の復習 その1:軽く見直す。
軽く見直しました。
このTutorialはほとんどUnityで解説されています。見ていて一寸しんどかったです。
それは兎も角として、前半部分はWorld SpaceとLocal Spaceの違いについての解説がほとんどです。そしてLocal SpaceやWorld Spaceの座標に対してTextureを貼り付ける実装方法が解説されています。
World Spaceの座標に対してTextureを貼り付けるとProjectionになります。ただし、このProjection方法だとObjectの形状によってはかなりの歪みが生じます。この歪みを直すためにこの偉大なProjection Seriesが始まる訳です。
3.4 Using Position Data - Shader Graph Basics - Episode 26 [6]の復習 その2:前に勉強した内容を復習する。
2022-01-10のBlogで勉強していました。思っていたより最近でした。
中々よくまとまっていて読んでいてかなり勉強になりました。今、Tutorialを見たばっかりですが、ここにまとめられている内容で聞き逃してた部分が2か所ぐらいありました。
最初に軽く動画を見てからどうやって勉強するのかの戦略を立てています。
この戦略が中々鋭くて、今読んで思わず感心していまいました。
一寸気になったのが、以下の文ですが
Local Positionノードが返すのはそのMaterialを使用しているObjectのVertexのLocal Spaceにおける座標だと思いました。
この辺はそれぞれのSpaceに対して曖昧な定義で勉強していたのでそういう曖昧な表現になったんでしょうね。
でも真剣に考えると今でも良く分からない部分もあります。
この辺はもう一回勉強する時に復習します。
曖昧と言えば、Spaceと座標軸の言葉の定義も非常に曖昧なままで使用しています。
これってかなり数学な話かもしれませんが、空間があってその空間内でObjectの位置やそのObjectが持っているVector的な特性(例えば速度など)を表すために座標軸が発明されたと考えるのか、座標軸があるから空間があると考えるのか、によって厳密な意味での言葉使いが変わります。
前者の考え方なら「Local Spaceにおける座標軸は…」と言う言い方が正しくなりますが、後者ならLocal Spaceと言っただけで即Local Spaceの座標軸を表している事になり「Local Spaceにおける座標軸は…」と言う言い方は同じ事を2回繰り返している事になります。
直観的には座標軸があったって空間を作成する事は出来ないので前者が正しく思えます。しかし仮想空間では座標が存在する事イコールその空間が存在する事です。つまり後者の考え方が正しくなります。
今の時点では前者の考え方の方がしっくりくるので「Local Spaceにおける座標軸は…」と言う言い方で統一していこうと思います。
3.5 Using Position Data - Shader Graph Basics - Episode 26 [6]の復習 その3:もう一度勉強する。
勉強のやり方ですが、前回やった以上の上手い方法は思いつきません。同じ方法で勉強します。同じ方法で勉強しますが、今回は正しいProjectionを作成するために必要な理論と知識に注目しながらそれぞれの実装を検証する事にします。
このTutorialで勉強するのは以下の3つのNodeについてです。
これらのNodeを使用するためには、それぞれの空間とその座標について理解する必要があり、その部分が理解出来ないと結局使用出来ないので、そこを理解出来るように解説しているのがこのTutorialの肝です。
しかしその辺は細かい点は兎も角として大まかな理論は既に理解していますので、簡単に行く事にします。
<Local Position>
最初の実装です。
Review上の結果です。
この実装の目的は、Local SpaceのXの値がLevel上で移動しても変化しない事を示す事です。
Level上で移動させてみました。
このMaterialを使用したObjectをLevel上で移動しても色の変化はありませんでした。
しかしLocal Positionの値がWorld Spaceの位置によって変化しない事を示すためなら、
の方が分かり易いのでこっちも試します。
はい。全く色が変化していないのが観察出来ました。
<Object Positionノード>
次にObject PositionノードがWorld Spaceの座標軸におけるそのObjectのPivot の値を示している事を確認するための実装をしています。このNodeはProjectionには使用しないのでここではスキップします。
<Absolute World Positionノード>
の場合は、そのObjectのWorld Spaceにおける位置を色で表しているのでLevel上で移動すると色が変化します。
これだけです。このTutorialでProjectionのために理解する必要があるのは。
<Projectionの実装>
そして実際にAbsolute World Position ノードを使用してTextureをProjectionしてみます。
以下の実装でProjectします。
ここの実装のPointはTextureは平面であるため、TextureをWorld Spaceの座標に貼る為にはXYZ軸から2つの軸を選んでTextureを貼る必要がある所です。
上記の実装ではXY軸で平面を作成しています。
XY軸で平面を作成しているからZ軸(上面)から見ると歪んでないんですね。
納得です。
Level上で移動してみます。
Top Viewからの撮影です。見事にProjectionしています。
少しだけ斜めから見ました。
斜めから見ると歪んでいるImageも確認出来ます。
3.6 Using Position Data - Shader Graph Basics - Episode 26 [6]の復習 その4:Projectionの観点からのまとめ
ここではWorld SpaceにおけるObjectのVertexの値を示すAbsolute World Positionノードを使用したTextureのProjectionについて勉強しました。
Absolute World PositionノードのRGの値をTextureのUV値としてパスするとWorld SpaceのZ軸に対して歪みのないProjectionを行います。
この方法をRB、GBにも拡張する事で歪みのないProjectionを作成するためのTri-Planar Projectionに繋がる訳です。
しかしこの方法は4つのTextureを隣接させる訳でその4つのTextureをSeamlessに接続するのは難度が高くなる事もこの時点で宿命づけられていますね。
4.Prologueの作成
4.1 作成したPrologueをRPGに組み込む
Prologueの試作を作ったProjectのVersionが4.26だったので4.24で作成しているRPGに直接Migrateすると認識してくれませんでした。ので最初から作り直しました。
こんな感じになりました。
4.2 作成したPrologueのセリフを直す
<一枚目>
無難な名前を考える必要があります。
主人公の名前の決め方には、隠れたメッセージを込めると良いそうです。
- 僕の名前は○○です。小学5年生です。
- 今は夏休みでおばあちゃんの家にいます。
- 今日から三日間、おばあちゃんの家に泊まる予定です。
に変更しました。
<二枚目>
以下の文章に変えました。
<三枚目>
これは沢山直す必要がありますね。
まず激怒と言う言葉が強すぎます。いや強い表現は必要なんですが、怒ると言う表現が主人公の感情の表現として極度に偏ったものになってしまっています。
- 銀河鉄道の夜の結末に僕はショックを受けました。
- 「何で親友のカムパネルラが死ななくちゃいけないんだ!」
- ショックを和らげるために僕は散歩に出かけました。
こっちの方が柔らかい感じがします。
ただショックの代わりにUpsetを使うのも面白いと思っています。「僕はUpsetしました。」って綺麗な表現だと思います。
<4枚目>
あんまり説明的な文は省く事にします。
- 気が付いたら森の中の神社まで歩いていました。
- 折角なので「神様、何でカムパネルラが死ななくちゃいけないんでしょうか?続きの物語で生き返らせて下さい。」とお願いしました。
としました。
<5枚目>
ここの文章はAnimationを完成させた後でまた直します。
取りあえず以下の様にしました。
- その日の夜、眠れないので布団の中でじっとしていると、お化けが現れました。
- そしてお化けは、こう言いました。
- 「カムパネルラを息かえらせたいのなら明日の夜、もう一回神社に来なさい。」
<6枚目>
一文が長いです。
ここは主人公がおばあちゃんに内緒で夜中に家を抜け出して神社に行くという選択をする大事な場面なので文を分けます。
- 次の日、僕はお化けの話がとても気になりました。
- なのでその夜、おばあちゃんの家を抜けて一人で神社に行きました。
- 勿論、おばあちゃんには内緒です。
<7枚目>
ここもAnimationが完成した後で直します。
- 神社に着くと昨日のお化け達が目の前に現れました。
- お化けが言いました。「本当に来たのかい。勇気があるね。奥に神様が待っているよ。」
- 僕はお化けに言われるままに神社の奥に行きました。
<8枚目、その1>
ここの一枚目は電車のImageは抜きます。
- 僕が神社の奥に行くと、綺麗なお姉さんが居ました。
- お姉さんが言いました。「よく来ましたね。君がカムパネルラ君を生き返らせたい少年ですね。」
- 「カムパネルラ君を生き返らせるためには、金の切符が必要です。」
このセリフの後で電車が来るアニメーションを追加します。
<8枚目、その2>
ここはもう少し考える必要がありそうです。
取りあえず直しました。
4.3 電車の3Dモデル
銀河鉄道は出来れば電車の3D Modelがあると良いなと思っていましたが、調べたら2個無料の電車がありました。
見てみます。
<City Subway Train Modular>
これ専用にProjectを一個作成しました。
凄い時間がかかってやっとProjectを見る事が出来ました。
電車内の3D だったのか?
それは兎も角作りが凄いです。
パーツの一覧でしょうか?
これ見ると電車を一から組み立てる必要がありそうですね。
一寸望んでいたモデルとは違うようです。
<Train Yard>
こっちは電車はあるみたいですね。
兎に角サイズが大きいです。
デモ画面を開きました。
電車が一台ありました。
かなり良いんじゃないでしょうか。
Asset一覧です。
電車は一種類しかないみたいですね。デモに出て来たヤツでしょうね。
近づいて確認したら電車のExampleってなっています。
電車はModularを使用して組み立てるみたいですね。
BPで一塊にしておいてくれると使いやすかったんですがね。
電車の中です。
これそのまま使用したいですね。
流石にこれを組み立てて使用出来るようにするのは重労働ですし、私の得意分野ではありません。
デモにある電車を一塊のBPにしてExportして使用出来るか試してみます。
5.Open Worldの検証
5.1 公式のDocumentであるGrass Quick Start [7] を勉強する
Procedural Foliage Toolを勉強するためにOpen World Tools [8] にあるTutorialからGrass Quick Start [7] を選択しました。
多分ですが、ここで習う内容は前にLandscapeを作成した時に使用しているはずです。しているはずですが、前に勉強した時はその部分の名称がProcedural Foliage Toolと言う事は知りませんでしたし、Materialの知識が不十分だったせいで、勉強した内容をしっかり覚えていませんでした。
ここでしっかり勉強しておきます。
<1 - Prerequisites>
Open World Demo CollectionをDownloadします。
既にしてありました。
何とこのAsset、Version 4.25 までしか対応していません。前にVersion 4.24で作成したTest Environmentに追加します。
<2 - Initial Level Setup>
Landscapeを追加しました。
更にLandscapeにデコボコを付けました。
<3 - Grass Tool Actor Creation and Setup>
Grass Toolが正常に作動するために必要なMaterialとActorを作成します。
Landscape Grass Typeを作成します。
ここが前にやってやり方を忘れてしまった部分です。しっかり記録しておきます。
Landscape Grass Typeを選択します。
Grass_00と名付けました。
Grass_00を開きます。
Grass MeshにSM_FieldGrass_01をセットしました。
更にTutorial通りに以下の設定もセットします。
元々チェックされていました。
あれ、Finished Stepが既にCheckされています。
前に勉強した事あるのか?
まあいいです。どんどんやっていきます。
<4 - Landscape Materials and the Grass Tool>
Landscape terrain とthe Landscape Grass Typeの両方に働くMaterialを作成します。
前に勉強した時は、Materialの知識が不十分だったのでこの部分の理解が足りなくてやり方を忘れてしまった気がします。今回はこの部分をしっかり勉強します。
まずMaterialを作成します。
Tutorialが言う通りにMAT_GT_Grassと名付けました。
Epic Game社の公式のDocument内ですら公式で進めるNaming Conventionを守っていない現実。MaterialはM_を使用するとは何だったんでしょう。
MaterialのBPを開いて以下のTextureを追加します。
更にLandscape Layer Blendノード、Landscape Layer Sampleノード、そしてLandscape Grass Outputノードを追加します。
このLandscape Layer Blendノードは、何回も出て来たノードですね。ここできっちり使い方を覚えてしまいましょう。
Layer Blend ノードを選択してLayerを2つ追加します。
Tutorialの指示通りに値を追加します。
うーん。この値の意味何かあった気がしますが覚えていません。後で変えれたような気もします。
以下のように接続しました。
次はLandscape Grass Outputノードの設定です。
Grass Typeに先程作成したLandscapeであるGrass_00をセットします。
今度はLandscape Layer Sampleノードの設定を行います。
Parameter Name にGrassをセットします。
更にLandscape Layer SampleノードをLandscape Grass Outputノードに接続します。
うーん。
前にLandscapeを作成した時はこれを勉強して作成したみたいですね。
Landscape4を作成した時に、全く同じやり方で草を生成した記憶があります。
<5 - Using the Grass Tools>
先程作成したMaterial、MAT_GT_GrassをLandscapeに使用します。
Landscapeを選択してLandscape MaterialにMAT_GT_Grassをセットします。
ModeをLandscapeに変更してPaintを選択します。
はあ。思いだして来ました。
このRockとGrassを指定するんですわ。
Rockにある+を押します。
Weight-Blended Layer (normal)を選択します。生成されるFileを保存する場所を聞いてくるので適当に選びます。
今度はGrassを選択します。
ViewportにCursorを置いてMouseのLeft ButtonでGrassをLandscape上に塗り込みます。
Layerが無いから塗り込めませんと出て来ました。
Rockと同じ方法でLayerを作成します。
でも出来ません。同じ警告が表示されます。
あれ?
今度は以下に示した様にGrassの部分が色分けされるようにGrassを選択しました。
今度はMouseのLeft ButtonでGrassをLandscape上に塗り込めました。
あれ出来てないじゃん。と思ってLandscapeに近づいて見ると草が確かに生えていました。
でもTutorialのImageとは全然違います。
Landscape Grass Typeに指定されている
Grass MeshはTutorialが指定したモノになっています。
うーん。まあいいでしょう。
今回の目的であるProcedural Foliage Toolの使い方の勉強は出来ましたし、更に前回、Landscapeを作成した時の方法も少しだけ思い出して来ました。
5.2 World MachineのUser Guide [8]を読む
先週、少しだけWorld Machineの勉強をしたんですが、Versionが変わったせいかSmart Poly氏のHow To Make A Massive Open World Map In Unreal Engine 4 [9] のWorld MachineのTutorialが全く違っていて同じように出来ません。
そこで少し調べたら以下のBPを勉強した方がWorld Machineの使用方法について理解出来そうなので、それを試してみます。
このWorld Machine社が作成したUser Guide [8]しか現状資料が無いのでこれを読みます。
これも古すぎて今のWorld MachineのVersionに対応していない、もしくはFree Versionに対応していない場合は、World Machineの勉強は一端中止にします。
<1.An Introduction to World Machine>
World Machineは他のTerrain 生成 Programと違い procedural levelでTerrainを作成するとあります。これはWorld Machine はterrainを生成するStepを指定してTerrainを生成し、他のTerrain生成Programのように実際にTerrainを描く事はしない事を指しているそうです。
うーん。
ぶっちゃけ、これってPerlin NoiseでHeight Mapの高低を指定しているだけじゃないの?
と思っているんですがどうなんでしょう。
<<Concepts you should know>>
以下のConceptを知っておく必要があるそうです。
- Worlds:World Machineで組み立てられた世界の事を指している様です。
- Devices:UEのBPでいう所のNodeを指している様です。
- Workview:以下の画面を表示している所を指している様です。
- Build:Work viewで組み立てたProgramで実際にWorldを生成する事を指している様です。
<<The Starting World>>
ここでも用語の説明がしてありました。
Worldは以下のWorkflowを指している様です。
前の解説では曖昧だったWorldの定義がしっかりしました。
Buildについてです。
Buildするためには以下のToolを選択するか、
ProjectにあるBuildを選択する必要があります。
これはC++のBuildのConceptをそのまま応用している感じです。
要するに使用出来る状態にするのがBuildって事です。
予測に反して中々分かり易い説明です。一寸気に入りました。もう少しだけやる事にします。
<2. Device Workspace>
<<Device Workview>>
成程、WorkviewとWorldの違いが分かりました。WorkviewはWorldを表示しているViewを指しています。以下に示した部分です。
<<Devices>>
やはりDeviceはUEのBPのNodeを指しています。以下にDeviceの例を示しておきます。
PortsはDeviceの辺にある黒い半円を指しています。Dataの出し入れを行います。左側についているPortをInputsと言い、このDeviceに入っていくDataを管理します。反対に右側についているPortはoutputと呼ぶそうです。これはこのDeviceから出力されるdataを管理します。
Deviceの底についているPortはmask input portと言うそうです。これの役割は良く分かりませんでした。Deviceの上に付いている小さなPortはparameter portと言うそうです。これについては後で勉強するそうです。
後、先週の予測通り、以下の部分で制作し
次の部分で編集し
最後の部分で出力していました。
<<<Add a new device>>>
Deviceを追加するための色々な方法が紹介されていました。
試しにAdvanced Perlin Deviceを追加してみました。
Tab Keyを押してDeviceを追加するのはWorld Machine特有な気がします。
<<<Selecting & Moving Devices>>>
ここではDeviceの選択方法について解説しています。
<<<Device Status>>>
以下の赤で囲った部分の色についての解説です。
緑色は、正しく接続されかつBuildも成功している状態です。
薄い緑色は、正しく接続されていますがBuildはされていない状態です。
これは再現出来なかったです。
赤は正しく接続されていない状態です。
<<<Wiring Devices>>>
二つのDeviceの繋げ方です。
大体UEのBPと同じです。
かなり違うのは以下の二つだけでした。
Wireを外す時は、外したいWire上でMouseの右クリックをして以下に示したようなBoxを表示させてDelete wireを選択します。
Routeを表示させる方法ですが、WireをクリックしてDragします。
UEのようにDouble Clickではないです。
<<Groups>>
GroupはUEのBPにおけるCommentと同じ機能です。
<<<Group Creation>>>
Group化したいDevicesを選択して右クリックします。すると以下の様なBoxが表示されるので、Group selected devicesを選択します。
以下の様になりました。
もしくは以下のToolを選択してGroup化したいDevicesを囲みます。
これも試してみました。
<<<Group Manipulation>>>
Groupを選択するとそのGroupとそのGroupに含まれる全てのDevicesを動かせます。
Group同時が衝突した場合、ぶつけられた方のGroupは移動して場所を開けます。
Floating Groupに変更すると他のGroupと衝突する事は無くなるそうですが、そのやり方は分かりませんでした。
<<<Editing a Group>>>
Groupの表示の編集画面です。GroupをDouble Clickすると表示されます。
Floatingはここに有りました。試してみたら本当に他のGroupと衝突しなくなりました。
因みにDeviceをClickするとそのDeviceのParameterの編集が出来ます。
以下にAdvanced Perlin DeviceをClickした場合を示しておきます。
<<Workview Commands>>
Workview Commandって何の事かと思ったらEditに表示されているCommandの事でした。
<<Device Commands>>
Device Commandは以下に示したBoxの事です。
Deviceを右クリックする事で表示されます。
それぞれのCommandの簡単な説明がここでされています。必要になったらここに読みに戻ります。
<<Tools>>
以下の部分についての説明です。
Tutorialではこの部分でOverlayについて説明していますが、そんなボタンないですよね。
一応、一通り読みました。何となくは理解しました。実際に使用する時にもう一度勉強する事にします。
流石にWorld Machineの勉強はもう飽きました。また来週、勉強する事にします。
5.3 How To Make A Massive Open World Map In Unreal Engine 4 [9] のWorld Machineの部分をもう一度見る。
勉強と言う訳ではないですが、もう一回、How To Make A Massive Open World Map In Unreal Engine 4 [9] のWorld Machineの部分を見てみます。
先週よりは理解出来るはずです。
やっぱり先週分からなかった
は、
の事だと思います。
上記のShape deviceで以下のTerrainをPolygonで作成して
Advance Perlin Deviceにパスすると
こうなりました。
こっちがTutorialで作成したTerrainです。
何となく似てます。
Tutorialには以下の様なScaleが表示されていますね。
次はProject Settingです。
Tutorialは有料版で、この部分は有料版のみに追加されているみたいな話を、先週、どこかで読んだ記憶があります。
私のProject Settingも開いて見ました。
うーん。大体同じみたいですね。
有料版しかない機能ってResolutionのサイズの事を言っているんでしょうか?
試しにTutorialと同じ数値にしてみました。
あれ。Terrainが消えた。
もう一回作成し直しました。
Advance Perlin Deviceを見ると
ぎゃ。なんじゃこれ?
やっぱり4km位で良いです。
直そうとしたら滅茶苦茶になってしまいました。
キリが良いので今週のWorld Machineの勉強はここまでにします。
6.他のMapの作成
6.1 雪山のLandscape用のMaterialの検証
先週、Winter Forest SetのLandscape用のMaterialを見たら、Result Nodeが以下の様な設定になっていました。
実は2021-04-04のBlogと2021-04-11のBlogでFlat Tessellationについて勉強しています。更に2021-12-06のBlogではContent ExamplesにあるFlat Tessellationについて検証しています。
今週はこれらの復習をします。
思いだして来たんですが、確かこのBlogでFlat Tessellationの意味を完全に解明した記憶があります。
この部分です。
Float Tessellationは平らで、PN Triangleは少し膨らみます。
すっかりこれを勉強した事を忘れてしまっていました。
この週のBlogを読むだけでTessellationに関する知りたかった事が全部理解出来ました。
そこに書かれている事そのまま書きます。
まずこれはDisplacement Mappingと言う技術で、Bump MappingのようにObjectの表面をデコボコにするためのものです。
正しBump Mappingとは違い実際にVertexを追加で作成して表面をデコボコにします。
以下の様にTessellationをセットすると
Result Nodeの以下の部分が使用出来るようになります。
はい。
これについて調べています。
そしたらその意味も説明されていました。
要するに雪山のMaterialはTessellationを使用して地面にデコボコを追加していた訳です。
そのデコボコ具合をWorld Displacementは指定していた訳です。
うーん。
こんな事も勉強していたとは。
ついでにこっちのBlogも読んでおきます。
ここは実際のLandscapeに使用している自作のMaterialにTessellationを実装した時の様子が記録されていました。
<Flat TessellationもしくはDisplacement Mappingのまとめ>
最初は一寸で理解の足しになれば良いと思ってBlogの復習をしましたが、Blogの復習で全部事が足りてしまいました。と言うか自分でまとめた内容が一番分かり易かったです。
やっぱり記録しておく事は大切です。
<来週の予定>
M_MASTER_LANDSCAPEのWorld Displacement を見ると以下のような実装になっています。
これについて検証します。
6.2 Landscapeの作成方法の復習
Landscape4をどうやって作成したのかの復習をします。
2021-03-15のBlogから復習します。
これ先週、「次の週にやります。」と言っておいてすっかり忘れていました。
結構大変なやつになりそうです。
2021-03-15のBlogではLandscapeのサイズを決定するのに悩んでいます。公式のDocumentであるLandscape Technical Guideにお勧めのサイズ表があるのでそれをみて決めています。
Component 、Section そして Quadの定義を忘れてしまったのでそれを勉強し直してから決定したいと書いています。
Component 、Section そして Quadの定義は又も忘れてしまいました。
Landscapeの作成にあたりTutorialの選別を行っています。
最終的には以下のTutorialをやる事にしたようです。
Landscapeの最小単位やSection Size、Component とSectionの関係がまとめられていました。
これは分かり易い。自分でまとめたんですが一番分かり易いです。
このTutorialのManaging our Landscapeで
と書いています。これってWorld Compositionについての説明ですよね。
この時には理解出来ないのは当然でした。
後気になる事と言えば以下の箇所に
Component毎にHeight Mapを管理しているとあります。
これが事実ならComponent 毎のHeight Mapを作成すれば幾らでも巨大なOpen World の作成が出来るって事でしょう。
それで2021-03-15のBlogにあった
が生きて来るわけですね。
ちょっと脱線しますがそうすると結局、公式のDocumentであるLandscape Technical Guideのお勧めサイズが最大になってしまいますね。
これだと8km^2ですね。これはWorld Compositionをしてもこのサイズが限界と言う事何でしょうか?
この後、更にTutorialで今日勉強したProcedural Foliage Toolを使用しています。ただしやり方しか理解出来てないみたいです。
LandscapeのLayerがどちらを採用しているのかDebugする方法が載っていました。
これは凄いです。
結論から言えば、
はもう一回勉強する必要がありますね。
ではLandscapeの水の表現について調査しています。これは雪山でも砂漠でも必要ないので後回しにします。
その後で、UE SenseiのTutorialを見つけてそれで勉強する事にしています。
ここで始めてMaterialにあるMacro variationと言う概念を勉強します。
更にここでは質の高いTextureを使用するために初めてBridgeをDownloadしてMega Scanを使用しています。
最後に自分の作成したLandscapeのTextureの繰り返しのImageをMacro variationやDistance Blendを使用して直しています。
実際のLevel上でLandscapeのTextureの繰り返し感が消えるように調整しています。
それ以外にもWorld Aligned Blendを使用して山の岩肌のTextureを調節しています。
量が多すぎて全部を把握するのは無理です。
来週、このためだけに時間を取ってまとめ直します。
Displacement Mapの勉強とそれを実際のLandscapeに適応させています。
後はLandscapeの沼を完成させました。
最後にMap1用のLandscapeを完成させています。
<Landscape勉強内容まとめ>
これは内容が濃すぎて一回で復習出来る量ではなかったです。沢山勉強するのも大切ですが、後で復習したり読み直したりする時に分かり易いようにまとめておく事はもっと大切でした。
このLandscapeの勉強は重要なので来週もう一回読み直して、今度は綺麗にまとめます。
一応、今週、理解した範囲でLandscapeの勉強内容を記しておきます。
- Landscapeの最小単位やSection Size、Component とSectionの関係
- Layer Blendを使用して荒れ地と緑を再現
- Procedural Foliage Toolを使用して草、木を自動で生やす
- Macro variationやDistance Blendを使用してTextureの繰り返しを見えなくする
- World Aligned Blendを使用して岩肌を手動で調整
- Displacement Mapを使用してTessellationで地面のデコボコを再現
ここに拾いきれなかったLandscape作成用に勉強した技術は来週、もう一度調査して追加します。
6.3 World Compositionの復習
これは来週やります。
7.Game Design:ポケモン+HxHの念能力( 戦闘システムの作成)
今週は対戦相手の召喚したMonsterが攻撃出来るようにします。
7.1 Player側のMonsterが攻撃する時のAlgorithm を復習する
2022-02-06のBlogにPlayer側のMonsterが攻撃する時のAlgorithmが雑にまとめられていました。これを整理すると以下の様になります。
- 左翼のMonsterが右翼のMonsterを攻撃
- 中央のMonsterが中央のMonsterを攻撃
- 右翼のMonsterが左翼のMonsterを攻撃
- いずれかのMonsterを倒したら勝利、そうでない場合は相手側のターン。
ダメージの計算方法です。
ジャンケンに勝った場合
- (HP-攻撃力*2)
それ以外
- (HP-攻撃力)
となっています。
実際の実装も見て行きます。
Game Mode内のEvent Player Actionに
Event Dispatcher であるEvent to Level Player Monster Fightを呼びます。
LevelBP上のEvent BeginPlay内でGame Mode内のEvent Dispatcher であるEvent to Level Player Monster FightはEvent Player Monster AttackにBindされます。
これでEvent to Level Player Monster FightがCallされたらLevel BP内のEventであるPlayer Monster Attackが実行されるようになりました。
Player Monster Attackでは、
最初にWidgetをパスしています。
このWidgetはPlayerの攻撃状況を表示するものです。
次にLevel BP上の6体のMonster BPの情報をそのWidgetにパスしています。
次にそのWidgetにPlayerのMonsterが対戦相手のMonsterを攻撃した事を表示します。
一秒待った後、実際に攻撃します。Playerの左翼側のMonsterが対戦相手の右翼側のMonsterを攻撃しています。
此処で対戦相手のMonsterが生きている場合は、次のMonsterが攻撃します。やる事は全く同じなので省略します。
対戦相手のMonsterが死んだ場合は、
Game ModeのBoolean 変数であるis Fight OverをTrue、Player winもTrueにセットします。そしてWidgetを閉じてGame ModeのEvent Fight Overを呼ぶ事で次のPhaseに移行します。
全てのMonsterの戦闘が終わってもどのMonsterも死ななかった場合、
Widgetのボタンが使用可能になります。
このボタンです。
何と、Game ModeのEvent Dispatcherが呼び出されていました。
このEvent Dispatcher、Level BP上で
Event Player Monsters Turn EndにBindしています。
Event Player Monsters Turn Endの実装は以下の様になっています。
次のPhaseに移行するための実装ですね。
以上でした。
7.2 Opponent(対戦相手)側のMonsterが攻撃出来るように実装する
最初はAlgorithmから考える必要があるかと思ったんですがPlayer側のMonsterが攻撃する時のAlgorithm や実装とほぼ同じで済むみたいなのでいきなり実装します。
Game ModeのEvent Opponent Action に
Event DispatcherであるEvent To Level Opponent Monster FightのCallを追加します。
このEvent DispatcherをGame Mode内のEvent BeginPlayからBindしました。
Bind したEvent、Opponent Monster Attackの実装部を作成していきます。
まずPassされたWidgetを変数に保持します。
次にOpponent(対戦相手)用の以下の部分を作成していきます。
Opponent Attack Widgetを以下の様に改良しました。
これはPlayer Attack Widgetと全く同じ作りです。
これを作成していて気が付いたんですがMonster Parameterの並びが順番通りじゃない気がします。後でMonster Parameterの名前をPlayer’s Monster Parameter Leftのような分かり易い名前に変更して確認します。
これでSet Monster BP to Widget()関数を使用してLevel BPにあるMonster BPをOpponent Attack Widgetにパス出来ると思ったら
出来ません。 パス出来るWidgetの種類をW Player Attackに限定していました。
うーん。これはPrototypeなんでWidgetの親クラスを作るとか面倒な事はしないで力技で解決します。
Opponent Attack Widgetをパス出来るSet Monster BP to Widget()関数と全く同じ関数を作成しました。
中身は一緒です。
次にセリフを表示します。
次にOpponentの左翼のMonsterがPlayerの右翼のMonsterを攻撃します。
この攻撃でPlayerのMonsterが死んだ場合を先に実装します。
Event Player AttackのOpponentのMonsterが死んだ場合とほぼ一緒ですがGame ModeのBoolean 変数であるPlayer WinがFalseにチェックされています。
残りのMonsterが攻撃する実装も追加します。実装方法は最初のMonsterが攻撃する場合と全く同じです。
全部のMonsterの攻撃が終わった後で、一体もMonsterが死んでいない場合は以下の実装を追加します。
Opponent Attack Widgetのボタンが押された時の実装を作成します。
Event To Level Helper Opponent Monster FightはLevel BP上でEvent Opponents Monsters Turn EndにBindしています。
Event Opponents Monsters Turn Endの実装を以下に示します。
これでOpponentに召喚されたMonsterも攻撃するはずです。
テストしてみます。
ボタンが押せるようになりません。
直します。
Opponent Attack Widgetであるべき所が、Player Attack Widgetになっていました。
直しました。
もう一回テストします。
最後、負けたんですが、Opponent Attack Widgetが消えません。
直します。
直しました。
もう一回テストします。
直っています。
何回か遊びましたが、バグはなさそうです。
意外ですがこの時点で既に面白いです。
7.3 戦闘の一例
戦闘の一例を紹介します。
開始ボタンを押します。
先攻後攻を決めるボタンを押します。
先攻に決まりました。
召喚するMonsterを選択し決定ボタンを押します。
先攻のMonsterが召喚されます。
後攻が先攻のMonsterを見て有利なMonsterの配置を行えないようにMonsterの正体が分からないようになっています。
先攻のMonster達が後攻のMonster達を攻撃します。
相手の番です。
どのMonsterも死ななかったので次のTurnになります。先攻後攻を決めます。
このTurnからは魔術師は魔法が使用出来ます。この魔法は相手を直接攻撃する事は出来ませんが、相手を眠らせたり、こちらの攻撃力をUpさせたりする予定です。
この部分の実装は来週からやります。
当然、相手の魔術師も魔法を使用してきます。
まだ実装していません。
先攻の攻撃が始まります。
後攻の攻撃が始まります。
2回程、戦闘を繰り返したのち
負けました。
8.UE5:Lumenの勉強
今週からLumenの勉強をします。
Naniteは、わけ分からない内から公式のDocumentを読み始めて理解するのにかなり遠回りしてしまいました。
今回は簡単なTutorialから始めて、何となく理解した後で、公式のDocumentを読み始めます。
今、分かっているのは、Lumenは一種のGlobal illuminationだと言う事です。
8.1 Unreal Engine 5 Lumen Tutorial - Beginner Friendly (UE5) [10] を勉強する
軽く見たんですが、Lumenの使用方法を分かり易く解説しているのでこれで勉強します。
<Lumenが使用出来る様になる為の設定>
Project SettingからLumenに関する設定を変更します。
以下の様にセットします。
更にGenerate Mesh Distance FieldsをCheckします。
rojectを再起動します。
普通に起動しました。
Lumen実験用の小屋をLevel上に作成しました。
Post Process Volume を追加します。
Post Process VolumeのDetailをLumenで検索して、関係のあるPropertiesを以下の設定に変更します。
テストのために以下のMaterialを作成します。
球にこのMaterialを適用します。
球を動かします。
後ろの反射光が球の動きによって変化しています。
一応これでLumenが出来た事になるのかな?
次にLight SourceのIndirect Lightingの値を変化させます。
Indirect Lightingが1の時は以下の様ですが
Indirect Lightingが5の時は
以下に示した様に中の球がかなりはっきり見えます。
以上でした。
9.Blenderの勉強
今週もImphenzia氏のLearn Low Poly Modeling in Blender 2.9 / 2.8 [11]をやっていきます。
9.1 先々週までの復習をする
覚えてなかった部分だけ書き残しておきます。
<以下の部分の名称>
<面を裏返しにする方法>
<以下の様に選択した面を自由に動かす方法>
この辺から全然覚えてないです。
<選択した面をXYZ軸に沿って動かす方法>
<Vertexを動かす方法>
全般的にGを押すとどうなるのかについて覚えていません。
ちなみにUEでGを押すと画面からPlay中に表示しないActorが消えます。UEの操作中に間違えてGを押して知りました。
<Pivot Pointの表示方法>
すっかり忘れていました。
<先々週までの復習のまとめ>
GやPeriod などのKey boardの機能については全く覚えていませんでした。
逆に画面をObjectを中心にして回転させる時にMouseのWheelを押してDragする方法なんかは馴染み過ぎて、UEの画面でやってしまいます。
UEの画面の操作は何となくやっている内に覚えてしまったので、いざ「コレコレをやるにはどうやるのか?」と聞かれると「エッ。」てなります。Blenderの操作方法はしっかり覚えてUEの操作方法と混じらないようにしたいです。
9.2 先週の復習をする
今度は先週のまとめと復習をします。
<Extrude:Cubeの6面の内4面を選択してその選択した面を繋げてExtrudeする>
これは何が言いたいのかと言うと
Cubeの4面を選択してExtrudeをすると以下のようになります。
これを以下の様にExtrudeしたいんです。
これのやり方ですが
です。
<Extrude:Cubeの6面の内4面を選択してその選択した面をバラバラにExtrudeする>
これも何を言っているのか分からないので以下に図を示します。
このようにExtrudeしたいんです。
やり方は
だそうです。
<もう一つのExtrudeする方法>
以下に示した紫色の部分のようなExtrudeをする方法です。
Ctrl を押したままMouse のRight ButtonをClickするとCursorのある位置までExtrudeします。
<回転>
これって以下の様なModelを作成するのであんまり好きな技術じゃないです。
一応覚えておきますが使用はしないと思います。
Key boardのR keyを押します。
<XYZ軸に沿って回転させる方法>
以下の様なModelが作成出来ます。
Rを押した後にKeyboardのX,Y,Zのどれかを押します。
<XYZ軸に沿って指定した角度だけ回転させる方法>
指定した角度だけ回転させる事も出来ます。以下の図はx軸に対して45度の角度で回転させました。
やり方は、R、x、45です。
R、回転させる軸(XYZのどれか)、回転させる角度になります。
<Inset>
以下の様に面に小さな面を作る方法です。
KeyboardのI keyを押します。
<以下に示した様なInsetの作成方法>
普通にやると選択した面をつなげて一個の面とみなしてInsetされます。
ので2つの面を選択してIを押します。
<以下に示した様なInsetの作成方法>
今度は面毎にバラバラにします。
ので2つの面を選択してIを2回押します。
<新しいObjectを配置する>
だそうです。
9.3 Imphenzia氏のLearn Low Poly Modeling in Blender 2.9 / 2.8 [11]の続きを勉強する
<Mirror ModifierとInsetについて>
これは後で詳しく解説するそうなのでスキップします。
Keyboard のB KeyがBoundaryだけ覚えておきます。
Mirror Modifierの使用方法が分からないので、自分で試す事が出来ないです。
<Proportional Editing>
Keyboardのoを押します。Vertexを一個だけ選択してGで移動させます。
以下に示した様なCircleが表示されます。
MouseのWheelを回転させるとCircleを拡大縮小出来ます。
すると以下に示した様に円の中のVertexは選択したVertexに対してProportionalに変化します。
以下のBoxからどのようなProportionalな変化をするのかの選択も出来ます。
<前に作成したMaterialを新しく作成したMeshに使用する方法>
新しく作成したMeshを選択してShading画面を開きます。
そしたら以下のマークを選択します。
すると今までに作成したMaterialが表示されるのでそれを選択します。
<木の箱を作る>
ここから木の箱を作成します。
今まで習ったTechniqueでここまで出来ました。
<Bevel>
Bevelって何と調べたら、これから作成する傾きの事そのものを指していました。
Ctrl+Bで出来るそうです。
Dragで長さを調節します。
現時点で凄くないですか?
Bevelを選択した時は画面の左下に以下のような表示がされるので
それをClickすると
が表示され細かい設定が出来るようになります。
例えばSegmentの数を増やすと
Bevelが以下に示した様に変化します。
これはSegmentを3にした場合です。
Low Polyではほとんど使用する事はないそうです。
<Shrink とFlatting>
以下に示したな凹ました面を
少しだけ更に凹ましたい時にSを押すと以下に示した様に選択した面を小さくしながら奥に移動します。
ここでAlt+Sを選択すると
選択した面のサイズが変わらないで奥に移動出来ます。
この部分の解説はゴチャゴチャしていて良く分からない部分があります。多分この解釈で合っているはずですが、もしかするともっと分かり易い違いがあるのかもしれません。
分かりました。
これ逆に大きくすると違いが良く分かります。
Sで大きくした場合です。
Alt+Sで大きくした場合。
これは違いが分かり易いです。でもこれをShrink とFlattingと呼ぶ理由は分かりません。
<Geometryを追加する>
新なObjectを作成するのではなくて今あるObjectに別のObjectを追加します。
内でShift+AでMesh、Cubeを選択。
Cubeが追加される。
<3D Cursorを動かす>
以下に示した点を3D Cursorと言います。
これの動かし方を習いました。
Shift+MouseのRight Clickです。
おお、確かに動きました。
でもそれがどうしたの?と思ったら
この3D Cursorのある位置に先程のGeometryが生成されるそうです。
試しにShift+AでCubeを追加してみました。
おお、3D Cursorの位置にCubeが追加されました。
<以下の面の中央に3D Cursorを置くにはどうしたら良いのか?>
Shift+Sで以下の表示がされるのでCursor to Selectedを選択します。
すると3D Cursorが選択した面の中心に表示されます。
Geometryを追加すると画面の左下に以下の様な表示が現れます。
これを開くと、以下の様に追加したGeometryの設定を指定出来ます。
あんまり沢山勉強しても覚えきれないので今週はここまでとします。
10.まとめと感想
今週はここまです。
何か熱っぽいのでこれで終わりにして寝る事にします。もしかしてコ○○かも。
11.参照(Reference)
[1] HEYYO CG. (n.d.). 【UE4.26】Niagara Advanced 解説基礎編~Particle Attribute Reader~ – HEYYO CG. Retrieved February 20, 2022, from https://heyyocg.com/ue4-26-niagara-advanced-particle-attribute-reader-basic/
[2] CGHOW. (2021, March 4). Particle Attribute Reader in UE4 Niagara Tutorial | Download Project Files [Video]. YouTube. https://www.youtube.com/watch?v=ZCkfBBHhPxg
[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=32
[4] 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=12
[5] 茄子 N. (n.d.). Unreal Engine 4 マテリアルデザイン入門[第2版] (GAME DEVELOPER BOOKS): Vol. 1 (2nd ed.) [E-book]. 秀和システム.
[6] Cloward, B. [Ben Cloward]. (2021b, December 9). Using Position Data - Shader Graph Basics - Episode 26 [Video]. YouTube. https://www.youtube.com/watch?v=Rm4ubzc-6Q4&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=26
[7] Epic Games. (n.d.). Grass Quick Start. Unreal Engine Documentation. Retrieved February 20, 2022, from https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/OpenWorldTools/Grass/QuickStart/
[8] World Machine. (n.d.). User’s Guide – World Machine Help. User’s Guide -World Machine -. Retrieved February 20, 2022, from https://help.world-machine.com/topics/manual/
[9] 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&list=WL&index=162
[10] vPoly. (2021, June 7). Unreal Engine 5 Lumen Tutorial - Beginner Friendly (UE5) [Video]. YouTube. https://www.youtube.com/watch?v=h5_4vAMqye4
[11] Imphenzia. (2020, June 25). Learn Low Poly Modeling in Blender 2.9 / 2.8 [Video]. YouTube. https://www.youtube.com/watch?v=1jHUY3qoBu8