UE4の勉強記録

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

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

f:id:kazuhironagai77:20220130233335p:plain

<前文>

<意外に深いツナマヨおにぎり問題>

他人に何と言われようと、ツナマヨおにぎりは美味しいです。

しかしこれ本当はMayonnaiseが美味しいんです。

アメリカに住んでいた時に、本場のMayonnaiseを食べたらまずくてびっくりしました。というかキューピーのMayonnaiseと全然味が違うんです。試しにキューピーのMayonnaiseをアメリカ人の友達に食べさせたらあまりの美味さに絶句してました。

今までアメリカ人でキューピーのMayonnaiseを食べてその美味しさに驚愕しなかった人に会った事がありません。それくらいキューピーのMayonnaiseは美味しいんです。

ただし「美味しい。」は主観的な感情だとも思っています。

私はアメリカに住み始めた時、メキシコ料理の豆がまずくて食べられなかったんです。しかし3カ月位たったある日、滅茶苦茶美味しく感じるようになりました。本当に突然その豆の味を美味しく感じるように変わったんです。

こういう現象は減量している人が減量しなくて良くなって普通の食事を取る時とかにも起きるみたいですね。

兎に角、脳の認識がまずいから美味しいに変化するんです。

これはネットで読んだだけなので話半分位に聞いてほしいですが、マウスに旨み成分のついた栄養の全くないゼリーを食べさせると、最初は狂ったように食べるんですが、2週間くらい経つと全く食べなくなるそうです。更にその味をまずいと認識する様になるそうです。

その論文では、味とその味から得られた栄養を脳が覚えていて、沢山栄養を得られた時の味を美味しいと認識しているんじゃないか?と推測していました。

自分のメキシコ料理の豆の体験からかなり納得して読んだのを覚えています。

美味しいにはそういう主観的な要素がある可能性もあります。

しかしそうは言っても世界中のほとんどの人はキューピーのMayonnaiseを非常に美味しいと感じます。

そしてツナマヨおにぎりはそのキューピーのMayonnaiseを大量に使って作っているだから美味しくなるに決まっています。

<Zero-knowledge Proofsと武術の秘伝>

私はComputer science専攻でしたが、専門が3d GraphicsだったのでZero-knowledge Proofsについては最近まで知りませんでした。もしかしたら一寸位は習ったのかもしれませんが全く記憶にありませんでした。それで最近になって知ったのですが非常に興味があります。

その理由なんですが、個人を特定されかねないので多少事実を脚色して更に曖昧に書きます。

あるAさんと言う人がいます。彼は合気道の達人みたく、腕をどんなにきつく抑えてもひょいと持ち上げて抑えている人を投げ飛ばせます。ここからがそのAさんと達人の違いなんですが、そのAさん曰く「心の持ち方を変えると誰でも出来る。5分で出来るようになる。」と言うんです。そして「その心の持ち方は本来、秘伝なので何十年も弟子として修業した人にしか教えないが、特別に○○万円払った人にはこの場で教えます。」と言うわけです。

それ聞いて詐欺だと思いましたが、証明は出来ていません。実際にAさん自身は、人をまるで餅でもちぎるかのように投げ飛ばす事が出来ます。しかし○○万円払ってAさんから秘伝の心の持ち方を聞いた人が5分でAさんのように人を投げ飛ばせるようになるかが問題で、その点が詐欺である事を私は証明したいんです。

勿論、Aさんが誰かにその心の持ち方を教えてその教わった人が一人でも人をAさんのように投げ飛ばせるようにならなければ詐欺の証明は出来ます。しかし○○万円をAさんに払うChallengeな人はまだ一人もいません。おそらくこれからもいないでしょう。

これ、Zero-knowledge Proofsを使用したらAさんの言う「秘伝の心の持ち方を聞くと5分で腕をどんなにきつく抑えてもひょいと持ち上げて抑えている人を投げ飛ばせるようになる。」が嘘である事を、秘伝の心の持ち方を聞かない状態で証明出来ないですかね。

<Non Fungible Token | NFTについて>

NFTって本当に唯一性を保証出来るんでしょうか?

最近、又聞きした話ですが、NFTが保証するのはPointerの唯一性だけでその先のObjectについては保証していないって話です。

これがどういう事を具体的に言っているのか分かりませんが、お金の保証みたいな事なんでしょうか?銀行にお金を預けますが、お金を下ろす時に、同じ紙幣は返さないですが、同じ金額を返します。これの事を言っているんでしょうか?

それより私が気になっているのは、誰かが書いた絵をネットに上げます。その絵を別な誰かが勝手にNFTに上げます。NFTが保証するのはどちらの権利なのかについてです。何となくですが後者の権利を強烈に保証しそうです。

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

<本文>

1.今週の予定

以下の内容をやっていきます。

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

もう先週の勉強の内容を忘れてしまったので、先週のBlogで復習しつつ今週の勉強をしていきます。

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

2.1 先週の課題

<先週の課題の復習>

先週のNiagaraの勉強で

f:id:kazuhironagai77:20220130233450p:plain

こう述べています。述べていますが何を検証するのかを覚えていません。

先週のBlogを読み直したら分かりました。

以下のImageをTexCoord[0]とnoiseのTextureから作成します。

f:id:kazuhironagai77:20220130233509p:plain

その実装方法を以下に示しますが、赤線で囲った部分でTextureのNoiseを線上に引っ張っています。

f:id:kazuhironagai77:20220130233726p:plain

これをやるのは別に回転させる前でもいいんじゃないの?

と思って以下に示したようにTexCoord[0]ノード内で赤線で囲った部分と同じ効果を設定したところ、

f:id:kazuhironagai77:20220130233751p:plain

以下に示した様な全然違う結果になりました。

f:id:kazuhironagai77:20220123232406g:plain

この原因を解明すると言っています。

<先週の課題の検討>

これはTexCoord[0]ノードにおける拡大縮小(Scaling)、回転 (Rotation)、の順番とPannerの効果の結果の変化についての問題です。

まずPannerの効果について確認します。

Pannerノードの効果を確認するために以下の実装を作成しました。

f:id:kazuhironagai77:20220130233917p:plain

結果です。

f:id:kazuhironagai77:20220130233929p:plain

何と動いていません。

PannerノードのSpeed XとSpeed Yの値をセットしていませんでした。

f:id:kazuhironagai77:20220130233946p:plain

先週の実装で一番重要な個所はPannerノードのSpeed の値です。その確認をしてなかったから先週は混乱したんです。

先週の実装のPannerの値を確認します。

f:id:kazuhironagai77:20220130234002p:plain

でした。

同じ値を代入します。

f:id:kazuhironagai77:20220130234022g:plain

左から右に移動しています。

それでは回転を追加してみます。

f:id:kazuhironagai77:20220130234051p:plain

Rotationの角度ですが、先週の実装で使用した0.85は360*0.85= 306なので分かりにくいので90度になるように0.25をセットしました。

結果です。

f:id:kazuhironagai77:20220130234107g:plain

まずこの効果を理論的に説明出来るか検証しましょう。

<<回転した後でPanner>>

2021-11-08のBlogで詳しく解説していますが、TexCoord[0]を操作するOperatorの効果を正しく予測するためには、仮想的なCameraがあると想像して、OperatorがそのCameraを操作していると考えると上手くいきます。

この辺で説明しています。

f:id:kazuhironagai77:20220130234129p:plain

このやり方はわざわざMatrixを計算しないでも直観的に結果を予測できる極めて優れた方法です。

今回もこの方法でTexCoord[0]ノードに回転を加えた場合どうなるかを検証しましょう。

Custom Rotatorノードを追加する前の状態です。

f:id:kazuhironagai77:20220130234149p:plain

カメラが写している部分です。

f:id:kazuhironagai77:20220130234206p:plain

Custom Rotatorノードの中身については2021-12-20のBlogで詳しく検討しているのでここでは結果だけ書きます。

以下の条件で回転させた場合、

f:id:kazuhironagai77:20220130234223p:plain

Rotation Centerの値が(0.5,0.5)なので以下の様にカメラが移動します。

f:id:kazuhironagai77:20220130234245p:plain

この状態のカメラから見たImageは以下の様になります。

f:id:kazuhironagai77:20220130234306p:plain

この後、0.25なので90度の回転がこのカメラに加わります。

私が自作したRotatorは反時計回りですが、Custom Rotatorノードの回転は時計回りです。2021-12-20のBlogでその事について述べています。

f:id:kazuhironagai77:20220130234328p:plain

なので以下のようになります。

f:id:kazuhironagai77:20220130234346p:plain

カメラに写っているImageです。

f:id:kazuhironagai77:20220130234403p:plain

最後に(0.5, 0.5)だけCameraが移動します。

f:id:kazuhironagai77:20220130234420p:plain

カメラから見たImageです。

f:id:kazuhironagai77:20220130234445p:plain

以下の結果と一致します。

f:id:kazuhironagai77:20220130234107g:plain

<<Scalingを追加する>>

次にScalingについて考えます。

以下に最後にScalingを追加した実装を示します。簡略化のためにPanner ノードは外しました。

f:id:kazuhironagai77:20220130234549p:plain

結果です。

f:id:kazuhironagai77:20220130234603p:plain

Smileの頭の部分だけが写っています。

f:id:kazuhironagai77:20220130234620p:plain

これが青の座標軸に沿ってカメラの大きさが変化します。X軸はそのまま、Y軸は10分の1になります。

f:id:kazuhironagai77:20220130234637p:plain

カメラから見たImageです。

f:id:kazuhironagai77:20220130234656p:plain

うーん。実際のImageと全く同じ形になっていますね。

今度は先にサイズを変更した場合です。

f:id:kazuhironagai77:20220130234725p:plain

最初の状態です。

f:id:kazuhironagai77:20220130234739p:plain

Pannerノードは外していますが、後で足す時に分かり易いようにPannerの矢印は残しておきます。

カメラから見たImageです。

f:id:kazuhironagai77:20220130234755p:plain

Scalingを適応します。カメラのSizeが水色の座標軸に沿って拡大縮小します。

f:id:kazuhironagai77:20220130234813p:plain

カメラから見たImageです。

f:id:kazuhironagai77:20220130234835p:plain

実際の結果と比較してみます。

f:id:kazuhironagai77:20220130234854p:plain

f:id:kazuhironagai77:20220130234900p:plain

はい。全く同じです。

次に回転を追加します。

まずカメラが(-0.5,-0.5)移動します。

f:id:kazuhironagai77:20220130234917p:plain

カメラから見たImageです。

f:id:kazuhironagai77:20220130234933p:plain

何も写っていません。

この予測に対しての実測における結果ですが、Custom Rotatorノードの中で行われているので実測が出来ません。

Custom Rotatorノードの実装を外で組めば出来ますが、結構大変なのでやりません。もし最終結果が最終予測と違っていたらやる事にします。

のでここからはしばらく予測だけになります。

今度は回転をカメラに対して加えます。

カメラは水色の軸の中心を中心にして90度、時計回りに回転します。以下の様になります。

f:id:kazuhironagai77:20220130234950p:plain

カメラに写っているImageは以下の様になるはずです。

f:id:kazuhironagai77:20220130235007p:plain

最後に(0.5, 0.5)移動します。勿論、カメラが水色の軸に沿ってです。

f:id:kazuhironagai77:20220130235024p:plain

カメラに写っているImageは以下の様になるはずです。

f:id:kazuhironagai77:20220130235041p:plain

これはCustom Rotatorノードを加えた後の結果と同じになるはずです。

f:id:kazuhironagai77:20220130235056p:plain

うん。大体同じです。

更に青色の矢印が示しているようにSpeed X =-0.5 のPannerを付けたら上に移動するはずです。

これも試してみます。

f:id:kazuhironagai77:20220130235156g:plain

成りました。

予測と完全に一致しています。

<先週の課題の検証結果のまとめ>

先週の疑問に対して検証して予測と実測した結果が100%一致している事を確認しました。ただ読み直すとかなり分かりにくいのでまとめ直します。

まず先週の疑問ですが、簡潔に書くと以下の様になります。

以下の計算と

f:id:kazuhironagai77:20220130235219p:plain

以下の計算の結果が

f:id:kazuhironagai77:20220130235234p:plain

同じになると思うんですがなってないです。後で検証します。

今、このように簡潔に整理した状態で見れば「行列の計算だからAxBとBxAの結果が同じになるわけないだろう。」と言えますが、先週の時点ではその辺すら分かっていませんでした。

2021-11-08のBlogで詳しく解説した「仮想のカメラを想定してそのカメラを動かすと実測結果と必ず一致する。」方法を用いてそれぞれの実装の場合の結果を予測しました。

その結果、二つの実装方法の結果はまるで違うもののなる事が確認出来ました。更にその予測は実際の結果とも完全に一致しました。

2.2 Happy New Year ! | Download Free UE4 Niagara Project [1] を勉強する

今週は何か、もっとNiagaraの勉強になるTutorialをやろうと色々CGHOW氏のTutorialを探していたんですが、Niagaraを多用しているTutorialは同時にStatic Meshを自作して使用しているんです。これはMesh RenderingがNiagaraの主力の一つである事を考慮すれば当然なんですが、そのTutorialを勉強するのに、そのTutorialで使用されているStatic Meshを作成する必要が出て来るのは予想外でした。

私がBlenderの使用方法を勉強したのは2.8以前で、今ではBlenderの使用方法は全く分かりません。先にBlenderの勉強をする必要が出て来ます。

ただし私はUEで使用するStatic Meshを作成するためだけにBlenderを使用するので

  • 3d Modelの作成
  • その3d ModelUV Mapの作成方法
  • UEへのExportのやり方

の3つだけ分かれば良いんです。しかも3d Modelに関しては、有機物を作成するんじゃないので単純な直線の組み合わせ+僅かに曲線の作成方法だけで作成出来る部分だけ勉強出来れば十分なんです。

こんなの一時間も勉強すれば十分なはずです。

しかしそう言う事を教えてくれるBlenderのTutorialは見つかりませんでした。

そうなると色々なTutorialを勉強して必要な部分を抜き出して自分でTutorialを作成し直すしかなくなります。それはどうやっても1時間では終わらないでしょう。2~3カ月は必要になります。2~3カ月もBlenderの勉強に費やすなら、DirectX 12とHLSLの勉強に時間を使いたいです。しかもまだUEの勉強も終わっていません。UEについて勉強する所はまだまだ沢山あります。

うーん。

出来ない事に手を出して全部駄目にするよりは諦めた方が良いかもしれませんね。Blenderに関しては時間がある時に色んなTutorialを視聴して、私が望んでいる部分だけ教えているTutorialに近いかどうかだけCheckする事にします。もしそういうTutorialが見つかったら速攻で勉強する事にします。

Happy New Year ! | Download Free UE4 Niagara Project [1]

CGHOW氏の色々なTutorialを見ていた時に気が付いたんですが、Happy New Year ! | Download Free UE4 Niagara Project [1]はTutorialではないんですが、その代り実装が無料で公開されていました。

f:id:kazuhironagai77:20220130235334p:plain

今週はこれの実装を検証する事にします。

<全容を把握する>

SampleをDownloadして開くと以下のようなBPが作成されていました。

f:id:kazuhironagai77:20220130235356p:plain

使用されているNiagara Systemは以下の3つでした。

f:id:kazuhironagai77:20220130235409p:plain

使用されているMaterialは意外に多くて以下の7つです。

f:id:kazuhironagai77:20220130235429p:plain

f:id:kazuhironagai77:20220130235437p:plain

f:id:kazuhironagai77:20220130235446p:plain

使用されているTextureは以下の2つです。

f:id:kazuhironagai77:20220130235503p:plain

f:id:kazuhironagai77:20220130235513p:plain

これで終わりかと思ったら、Material Parameter Collectionとして以下の二つが使用されていました。

f:id:kazuhironagai77:20220130235531p:plain

f:id:kazuhironagai77:20220130235540p:plain

更に自作のDirect Inputとして以下のBPがありました。

f:id:kazuhironagai77:20220130235555p:plain

更にLevel上を見ると以下のActorが配置されています。

f:id:kazuhironagai77:20220130235613p:plain

上3つは先程出て来たNiagara SystemのActorですが最後のPost Process Volumeは何をするために配置されているのか今一分かりません。取りあえずは無視しておきます。

<3つのNiagara Systemを調べる>

以下の3つのNiagara Systemを調べます。

f:id:kazuhironagai77:20220130235640p:plain

<Bokehを調べる>

Bokehです。

f:id:kazuhironagai77:20220130235659p:plain

Bokehって何の意味かと思って調べたら、日本語のボケが英語になった言葉でした。

ふーんです。

使用しているNiagara Effectは2つです。

f:id:kazuhironagai77:20220130235716p:plain

Fountain001が以下に示したScreenshotに写っている淡いオレンジ、

f:id:kazuhironagai77:20220130235733p:plain

Fountain002が以下に示した光の粒を生成しています。

f:id:kazuhironagai77:20220130235750p:plain

Fountain001から見て行きます。

使用しているMaterialはm_radial2です。

f:id:kazuhironagai77:20220130235818p:plain

これは後で見ます。

使用されているModuleの一覧です。

f:id:kazuhironagai77:20220130235836p:plain

結構初めて見るModuleがあります。

以下のModuleでCurl Noise Force とDynamic Material Parametersは使用した事がありますが、あんまり詳しくはないです。

Camera Offsetは名前から何をやっているのか大体予測出来ますがほぼ初めて見るModuleです。

Scale Colorはいつもは消してしまうModuleですが今回は使用されていますね。

f:id:kazuhironagai77:20220130235903p:plain

f:id:kazuhironagai77:20220130235911p:plain

今度はそれぞれのModuleの機能について見て行きます。

Particle Update Sectionにセットされている以下の3つのModuleですが

f:id:kazuhironagai77:20220130235927p:plain

これは結局Particle を移動させている訳です。

無くてもあんまり変わらない気がします。

試しに切ってみました。

f:id:kazuhironagai77:20220130235944p:plain

微妙な違いがありますね。

f:id:kazuhironagai77:20220131000004p:plain

ただしSpriteが動いている事は認識出来ません。

Spriteが動いている事は認識出来ないんですが、上記の3つのModuleを切ると何か質が落ちた気がします。

Dynamic Parameterですが

f:id:kazuhironagai77:20220131000020p:plain

Materialでは使用していません。

f:id:kazuhironagai77:20220131000035p:plain

どこで使用しているんでしょうか?

試しにDynamic Parameterを切ってみたんですが違いがあるのかどうか良く分からなかったです。

Fountain002です。

MaterialはFountain001と同じm_radial2を使用していました。

f:id:kazuhironagai77:20220131000056p:plain

使用しているModuleを以下に示します。

f:id:kazuhironagai77:20220131000118p:plain

こっちはSpawn Burst Instantaneous Moduleを使用してSpriteを生成していますね。

後、こちらはDynamic Parameterを使用していませんね。

Scale Sprite Size Moduleが使用されています。

設定を見るとUniform Scale FactorにSineが使用されていました。

f:id:kazuhironagai77:20220131000136p:plain

これでSpriteのサイズを変更しているのは分かるんですが何で自作しているでしょうか?

f:id:kazuhironagai77:20220131000157p:plain

Dynamic Input のGeneralにSineが二つあります。

f:id:kazuhironagai77:20220131000212p:plain

一個は元々備わっているヤツの気がしますが。

試してみましたが同じみたいですね。良く分かりません。

後は特に疑問はないですね。

<<追加>>

ここは後で気が付いたんですが、Bokehにもう一個Effectがありました。

f:id:kazuhironagai77:20220131000234p:plain

以下にこのEffectを示します。

f:id:kazuhironagai77:20220131000257p:plain

このEffectの特徴はMaterialにM_Bokehを使用している事で

f:id:kazuhironagai77:20220131000314p:plain

そのMaterial内にはDynamic Parameterがあります。

f:id:kazuhironagai77:20220131000331p:plain

更にそのDynamic Parameterの値はParticle Update SectionのDynamic Material Parametersで

f:id:kazuhironagai77:20220131000351p:plain

指定されています。

f:id:kazuhironagai77:20220131000406p:plain

うーん。この値が次のEffectのFountain001に残っていたんですね。

f:id:kazuhironagai77:20220131000423p:plain

謎が解明しました。

<<追加終>>

<Firework1を調べる>

Firework1をみます。

f:id:kazuhironagai77:20220131000441p:plain

名前の通り花火を担当していますね。

f:id:kazuhironagai77:20220131000459p:plain

以下の3つのEffectを使用しています。

f:id:kazuhironagai77:20220131000520p:plain

Rocketsです。

f:id:kazuhironagai77:20220131000534p:plain

Rocketだけ表示させたら何も写りません。

今の所???なEffectです。

Burstです。

f:id:kazuhironagai77:20220131000552p:plain

Previewの後ろの方に本当に僅かに火花が散っているのが見えます。

最後のEffectであるBurst_tailです。

f:id:kazuhironagai77:20220131000606p:plain

これは普通の花火ですね。

それぞれのEffectを見て行きます。

まずはRocketsからです。

f:id:kazuhironagai77:20220131000632p:plain

このEffectが見えない理由が分かりません。

Emitter Update SectionのSpawn Rate Moduleでは

f:id:kazuhironagai77:20220131000648p:plain

普通にSpawnしています。

f:id:kazuhironagai77:20220131000703p:plain

あ、分かりました。

Particle Spawn SectionのInitial Particle Moduleで

f:id:kazuhironagai77:20220131000719p:plain

Alphaの値が0にセットされていました。

f:id:kazuhironagai77:20220131000748p:plain

後、このEffectでは見た事がないModuleが2個使用されていました。

f:id:kazuhironagai77:20220131000810p:plain

Update Age Moduleは以下の解説がされていました。

f:id:kazuhironagai77:20220131000840p:plain

設定を見るとKill Particles When Lifetime Has Elapsedにチェックがついています。

f:id:kazuhironagai77:20220131001031p:plain

と言う事は、Particleの寿命がLife timeで設定した値を超えたらそのParticleは消滅すると言う事です。

うーん。

これってあえて指定しなくてもそうなっているんじゃないでしょうか?

このModuleの必要性が分かりません。

次はGenerate Death Event Moduleです。

f:id:kazuhironagai77:20220131001048p:plain

この解説を読むとこのModuleは消滅したParticleの情報をPassして何らかのEventを発するようですね。

設定を見るとそのParticleが持っているほとんど全ての情報をPassしていますね。

f:id:kazuhironagai77:20220131001102p:plain

でもこの情報を何処にPassしているのかが分かりません。

しかし以下のAnimationをみると次のEffectのParticleにパスしているように見えます。

f:id:kazuhironagai77:20220131001124g:plain

よおおく見ると白いEffectが消えた後に花火の火花が発生しています。

うーん。分かりません。

最後にSpriteに使用されているMaterialを見ます。

f:id:kazuhironagai77:20220131001147p:plain

HueがMaterial Parameter Collectionで指定されています。

f:id:kazuhironagai77:20220131001200p:plain

値は0で設定されていました。

f:id:kazuhironagai77:20220131001219p:plain

次のEffectを見ます。

Brustです。

f:id:kazuhironagai77:20220131001235p:plain

Effectです。

f:id:kazuhironagai77:20220131001252p:plain

非常に見えにくい小さな花火を作成しています。

まず注目したい点はEvent Handler SectionのEvent Handler Properties ModuleとReceive Death Event Moduleです。

f:id:kazuhironagai77:20220131001308p:plain

ここでRocketsのEventを受けていたんですね。

ただしこれのやり方全覚えていません。これは後で調べる事にします。

Event Handler Properties Moduleの設定をみると以下の様になっています。

f:id:kazuhironagai77:20220131001331p:plain

Spawn Numberとなっていますが、30のParticle が生成されるんでしょうか?

後、気になる点は、Emitter Spawn SectionでSet Emitter Ran Moduleがあり

f:id:kazuhironagai77:20220131001348p:plain

その変数RanをParticle Spawn SectionのAdd Velocity From Point Moduleで使用している所でしょうか。

f:id:kazuhironagai77:20220131001405p:plain

こんな感じで使用していますね。

f:id:kazuhironagai77:20220131001435p:plain

もう一つ気になるのがParticle Update SectionのGenerate Location Event Moduleです。

f:id:kazuhironagai77:20220131001458p:plain

こっちはParticleが生成された瞬間にEventを他のEffectに送るんでしょうか。

f:id:kazuhironagai77:20220131001516p:plain

これらのEvent Moduleの使用方法は何処かできちんと習わないと絶対に理解出来ないので、後で調べる事にします。

次のEffectを見ます。

Burst Tails Effectです。

f:id:kazuhironagai77:20220131001533p:plain

最も花火らしいEffectです。

f:id:kazuhironagai77:20220131001549p:plain

まず最初に注目したいのがここです。

Emitter Update SectionのSpawn Particle From Other Emitter Moduleです。

f:id:kazuhironagai77:20220131001604p:plain

ここで前のEffectのBurstに繋げています。

f:id:kazuhironagai77:20220131001620p:plain

更にParticle Spawn SectionでSample Particles From Other Emitter Moduleを使用しています。

f:id:kazuhironagai77:20220131001636p:plain

この辺の使用方法は後で調べます。

一回どっかで勉強した記憶がありますが、今は全く覚えていません。

<Happy New Yearを調べる>

最後にHappy New Year を見ます。

f:id:kazuhironagai77:20220131001657p:plain

最も目立っているEffectですが使用しているEffectは2つだけでした。

f:id:kazuhironagai77:20220131001711p:plain

Fountainの方は

f:id:kazuhironagai77:20220131001728p:plain

文字を表し、

Fountain001の方は

f:id:kazuhironagai77:20220131001743p:plain

黒いSmokeを表しています。

Particle Spawn SectionでAlign Sprite to Mesh Orientation Moduleが使用されています。

f:id:kazuhironagai77:20220131001759p:plain

初めて見るModuleです。

f:id:kazuhironagai77:20220131001817p:plain

だそうです。

別に普段どおりカメラに向かって整列しても良いと思いますが何で使用しているんでしょう。

ただそれは兎も角、このModuleの整列する方向が良く分かりません。

以下に示した様にZ軸とX軸に対してSpriteが広がっていますが

f:id:kazuhironagai77:20220131001829p:plain

設定はY軸とZ軸になっています。

f:id:kazuhironagai77:20220131001847p:plain

試しに

f:id:kazuhironagai77:20220131001901p:plain

に変更したら

f:id:kazuhironagai77:20220131001918p:plain

x軸に向かって文字が現れました。

後は特に気になるModuleはありませんでした。

典型的なMaterialが90%担当しているEffectです。

なので使用しているMaterial、HNY_Matを見てみましょう。

f:id:kazuhironagai77:20220131001935p:plain

ぬぉを。

f:id:kazuhironagai77:20220131001959p:plain

これは流石に複雑すぎる。

とは言うものの、読んだら下の部分のStarの実装以外は普通に理解出来ました。Starの所は軽く読んでいるだけじゃ意味が分かりません。が流石に今から全力で読む気にもなれません。

今回はこの部分の勉強はパスします。

後、NoiseのTextureが付属でついていました。

f:id:kazuhironagai77:20220131002014p:plain

今まで、Perlin Noiseしかなかったのでこれは助かります。

最後のEmitterです。

f:id:kazuhironagai77:20220131002036p:plain

これは薄い黒い弾幕を発しているだけのEffectです。ここに使用されているModuleは全て知っていました。

Align Sprite to Mesh Orientation Moduleがありますが、このEffectでは使用していません。消し忘れでしょうね。

以上です。

Happy New Year ! | Download Free UE4 Niagara Project [1]を検証して>

Event を使用してEffectを繋げる方法が分かりません。これは来週以降、勉強する事にします。

後は結構分かりました。

ただやっぱり勉強方法として「読んで終わり。」はあんまり良い方法とは言えませんね。実際にコードを書かないと本当に理解しているかどうかはっきりしません。

昔読んだ論文を思い出しました。

そこには教科書を読んで勉強しているGroupの平均点は、教科書に載っている問題を解いて勉強しているGroupの平均点と比べると勉強時間の長さに比べて非常に悪いとありました。その原因は教科書を読んだだけのGroupは間違って理解した内容が非常に多いからでした。

それ聞いて、問題を解いたGroupは単に答えを覚えてただけじゃねえ。とも思い、それに対する反証が載ってなかったので、点取り虫肯定の底が浅い意見とその時は思いました。

が、Programmingの勉強に関しては実際にコードを書かないと勉強にはならないですね。

今週は一寸時間を無駄にした気がしますね。

まあ、たまにはこういう時もあります。あんまり気にしないで次をやります。

3.Material :Projectionの勉強の続き

先週からの続きで今週は、Ben Cloward先生のTriplanar Projection Improvements - Shader Graph Basics - Episode 29 [2]を勉強します。

3.1 Triplanar Projection Improvements - Shader Graph Basics - Episode 29 [2] を軽く見る

今週、勉強する内容を把握するために最初に軽くTutorialを見ます。

見ました。

うーん。今回も神回でした。一体何をImproveするんかと思ったら今度は上下左右があるTextureに対応したTriplaner Projectionを作成します。

直す部分は二つありました。z軸の向きが逆になっている所と、Projectionが裏返しになっている部分です。

その後で作成したMaterialをMaterial Functionにする方法を解説しています。

今回は、UEで作成方法を解説していましたので分かり易かったです。

ただしUEとUnityは軸の設定が違うので原理をよく理解した上で適応する必要があり、Unityの解説を聞いた後でUEの解説を聞いた方がそういう原理的な部分の理解は深くなります。今回みたくUEの解説を先に聞いてしますとUnityの解説なんて聞く気にもなりません。

3.2 Triplanar Projection Improvements - Shader Graph Basics - Episode 29 [2] を実際にやってみる

それでは実際にやってみます。

今回はUV Grid Textureを使用する事でTextureの上下左右裏表をはっきりさせています。UE5に付属のUV Grid Textureがあるのか調べましたが見つかりませんでした。確かContent ExampleのSampleの一つにUV Grid Textureを使用しているのがあったんですが、それも見つかりません。

うーん。

Netから探す事にします。

https://polycount.com/discussion/186513/free-checker-pattern-textureにFreeで使用出来るUV Grid Textureがありました。

f:id:kazuhironagai77:20220131002126p:plain

これを使用させてもらいます。

規約を読むと特に作成者の名前を記録する必要もないそうなので、これからもUV Grid Textureが必要な時は使用させてもらう事にします。

f:id:kazuhironagai77:20220131002146p:plain

因みに、UV Grid Texture UnityとかUV Grid Texture Blenderだと沢山のUV Grid Textureが表示されますが、UV Grid Texture Unreal Engineだと一個か2個のUV Grid Textureしか表示されません。

<UV Grid Texture Unity

f:id:kazuhironagai77:20220131002217p:plain

<UV Grid Texture Blender

f:id:kazuhironagai77:20220131002236p:plain

<UV Grid Texture Unreal Engine

f:id:kazuhironagai77:20220131002256p:plain

こういう所を見るとUEがUnityなどに比べて庶民の受けが悪い気がします。まあ単なる主観ですが。

それは兎も角、今DownloadしたUV Grid Textureを先週作成したTriplaner Projectionの実装に使用します。

f:id:kazuhironagai77:20220131002311p:plain

こんな結果になりました。

f:id:kazuhironagai77:20220131002332p:plain

近づくと数字が逆向き裏返しになっている事が分かります。

f:id:kazuhironagai77:20220131002348p:plain

Blendされている部分です。

f:id:kazuhironagai77:20220131002404p:plain

近づいてよく見ないと分からないですがBlendしている箇所ははっきりしています。

この辺は上下は逆ですが裏返しにはなっていませんね。

f:id:kazuhironagai77:20220131002418p:plain

何もしなくても正常に並んでいる箇所もありました。

f:id:kazuhironagai77:20220131002431p:plain

<上下逆を直す>

まずはProjectionの上下の逆を直します。

Tutorialによると、上下が逆になっているのはx軸にProjectしたTextureとY軸にProjectしたTextureだけだそうです。Z軸にProjectしたTextureは上下の逆転現象は起きてないそうです。

この理由はそれぞれの軸をProjectする時に以下の方法でしますが、

f:id:kazuhironagai77:20220131002452p:plain

そのBの値のプラスとマイナスが逆になっているからだそうです。

Bにはz軸の情報が入っているのに向きが上下逆になっているのはxとy軸にProjectしたヤツって何か理不尽な気もしますが、Tutorialの説明通りにやってみます。

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

f:id:kazuhironagai77:20220131002509p:plain

Absolute World Positionのzの値に-1を掛けています。

結果です。

正面から見た図です。

f:id:kazuhironagai77:20220131002523p:plain

裏返しになっていますが上下は直っていますね。

Backから見た時です。

f:id:kazuhironagai77:20220131002538p:plain

上下も直っていますし裏返しにもなっていません。

うん。

元がどうなっているのかきちんと確認していませんでした。

最初からやり直します。

<<Front>>

f:id:kazuhironagai77:20220131002603p:plain

あれ、上下は逆ですが裏返しにはなっていませんね。

<<Back>>

f:id:kazuhironagai77:20220131002624p:plain

上下逆な上に裏返しです。

上下が逆なだけなら何とか文字を読む事が出来ますが、更に裏返しになると文字を読もうとすると気持ち悪くなりますね。

<<Right>>

f:id:kazuhironagai77:20220131002645p:plain

上下が逆なだけではなく裏返しになっています。

<<Left>>

f:id:kazuhironagai77:20220131002705p:plain

<<Top>>

一応、上から見た図も記録しておきます。

f:id:kazuhironagai77:20220131002728p:plain

所で上から見た時の上下ってどう決めるんでしょうか?

<<Bottom>>

f:id:kazuhironagai77:20220131002756p:plain

裏返っていますね。

確認出来ました。

さっきの実装を元に戻しました。

f:id:kazuhironagai77:20220131002816p:plain

もう一回見てみます。

<<Front>>

f:id:kazuhironagai77:20220131002833p:plain

ほら。上下が直りましたが裏表が逆になっています。上の掛け算を実装する前は、

f:id:kazuhironagai77:20220131002850p:plain

裏表は正しかったです。

この変化はどうして起きたんでしょうね。

<<Back>>

f:id:kazuhironagai77:20220131002903p:plain

Backも同じですね。裏返しが直った上に上下の逆も直っています。

<<Right>>

f:id:kazuhironagai77:20220131002931p:plain

これも上下の逆と裏返しが起きてその結果正常になっています。

<<Left>>

f:id:kazuhironagai77:20220131003002p:plain

Leftは上下は直ったんですが裏返しになってしまっています。

<裏返しを直す>

裏返すを直すためには以下のSignノードを使用する必要があるそうです。

f:id:kazuhironagai77:20220131003026p:plain

初めて見るノードです。Cursorを乗せると

f:id:kazuhironagai77:20220131003041p:plain

と解説されていました。

まずこのノードの前に何で裏返しにTextureがProjectされる箇所があるかと言うと、Objectの表面に対してどの面に対しても同じようにTextureをprojectするので、Objectの裏側の面は裏返しにProjectされるそうです。

うん。

分かったような分からない様な説明です。

自分流に解釈すると以下の図の様になります。

f:id:kazuhironagai77:20220131003100p:plain

ある点からTextureをObjectにProjectします。その点に対して向かい合っている部分はそのままProjectされます。逆を向いている部分はその部分からみて背中側にTextureがProjectされます。ので逆を向いている部分ではTextureは逆向きになります。

それでSignノードはどうやってこの問題を直すんでしょうか?

何と、逆を向いている面に対してはProjectionするTextureを逆向きにしてからProjectするそうです。

ほえ。

そんな発想は全然思いつかなかった。

まずはVertex Normal WSノードにSignを繋ぎます。

f:id:kazuhironagai77:20220131003159p:plain

結果です。

f:id:kazuhironagai77:20220131003218p:plain

正面です。

f:id:kazuhironagai77:20220131003235p:plain

0と書きましたが実際は-1かもしれません。

後ろです。

f:id:kazuhironagai77:20220131003253p:plain

これをどうするんでしょうか?

はい。次の部分でしっかり説明されていました。

以下にTutorialの説明を再現します。

まずMaskでRの値だけを抜き出します。

f:id:kazuhironagai77:20220131003310p:plain

このような白と黒の部分が出来ています。

f:id:kazuhironagai77:20220131003326p:plain

ここに先程のTextureを戻します。

f:id:kazuhironagai77:20220131003344p:plain

正面です。

f:id:kazuhironagai77:20220131003402p:plain

f:id:kazuhironagai77:20220131003412p:plain

後ろです。

f:id:kazuhironagai77:20220131003428p:plain

f:id:kazuhironagai77:20220131003438p:plain

はい。

Projectionが逆な部分は白く、Projectionと順な部分は黒く表示されている事が分かります。

次にBでMaskします。

右側です。

f:id:kazuhironagai77:20220131003533p:plain

f:id:kazuhironagai77:20220131003545p:plain

左側です。

f:id:kazuhironagai77:20220131003613p:plain

f:id:kazuhironagai77:20220131003622p:plain

Projectionが逆な部分は黒く、Projectionと順な部分は白く表示されています。

Rとは逆でした。

最後にBでMaskします。

上から見た図です。

f:id:kazuhironagai77:20220131003640p:plain

f:id:kazuhironagai77:20220131003651p:plain

順です。

下から見た図です。

f:id:kazuhironagai77:20220131003710p:plain

f:id:kazuhironagai77:20220131003726p:plain

Projectionが逆な部分は黒く、Projectionと順な部分は白く表示されています。

Bと同じでした。

あれ?

TutorialだとGが逆だった気が。

確かめて来ます。

X(R)が反対と言っていました。全く同じ結果でした。

あー良かった。

次に (-1,1,1)をsignの結果に掛けます。

f:id:kazuhironagai77:20220131003746p:plain

これでxの時だけ逆の結果になるように出来ました。

はい。

ここからが難しいpointです。

この結果をR,G,Bでmaskします。

f:id:kazuhironagai77:20220131003803p:plain

このRと以下のMask(GB)のGを掛けると

f:id:kazuhironagai77:20220131003820p:plain

逆になっている箇所が裏返るはずです。

同様にMask(G)とMask(RB)のRを掛けるとY軸面の逆になっている部分が裏返ります。

Z軸面も同様でMask(B)とMask(RG)のRを掛ける事で逆になっている部分が裏返ります。

うーん。

何で?

実際の計算から確認して見ましょう。

以下のようにX軸面だけ実装しました。

f:id:kazuhironagai77:20220131003836p:plain

Mask(G)がこれによってどう変わったのかを示します。

変更前です。

f:id:kazuhironagai77:20220131003854p:plain

変更後です。

f:id:kazuhironagai77:20220131003911p:plain

逆になっている!

うーん。そう言う事なのか。

さっきの絵で言えば奥の裏返しになっている部分のImageを180度回転させて

f:id:kazuhironagai77:20220131003933p:plain

裏返した状態でProjectionしている訳です。

f:id:kazuhironagai77:20220131003954p:plain

何となくですが理解しました。

全部直しました。

f:id:kazuhironagai77:20220131004015p:plain

結果です。

正面です。

f:id:kazuhironagai77:20220131004033p:plain

左側です。

f:id:kazuhironagai77:20220131004047p:plain

底側です。

f:id:kazuhironagai77:20220131004108p:plain

全部の箇所で裏返しが直りました。

3.3 Triplanar Projection Improvements - Shader Graph Basics - Episode 29 [2]をMaterial Functionにする

まずMaterial Functionを作成します。

f:id:kazuhironagai77:20220131004134p:plain

先程作成したMaterialの実装を全てコピーしてここに貼りつけます。

f:id:kazuhironagai77:20220131004152p:plain

結果をOutput Resultに繋ぎます。

f:id:kazuhironagai77:20220131004208p:plain

この実装をFunctionとして使用するためにはParameterがPass出来るようにする必要があります。例えばTextureです。好きなTextureをパス出来るようにしたいです。

それにはFunction Inputを使用します。

f:id:kazuhironagai77:20220131004223p:plain

今回はTextureをパスしたいのでInput TypeにFunction Input Texture 2Dをセットします。

f:id:kazuhironagai77:20220131004241p:plain

以下の様に実装します。

f:id:kazuhironagai77:20220131004258p:plain

今度はTextureのサイズをControlするParameterを追加します。

前のやり方と同じ様にまずFunction Input ノードを作成します。

f:id:kazuhironagai77:20220131004312p:plain

これはAbsolute World Positionに対して使用するのでVector3のままで良いです。

f:id:kazuhironagai77:20220131004327p:plain

こんなFunction になりました。

f:id:kazuhironagai77:20220131004412p:plain

f:id:kazuhironagai77:20220131004419p:plain

<Blend部分の手動による調整>

Blendしている部分の幅を調節するためのFunction Inputを追加します。

f:id:kazuhironagai77:20220131004445p:plain

このPowerの部分はBlend部分の幅を調節していたんでした。

うーん。今知りました。

結果です。

f:id:kazuhironagai77:20220131004501p:plain

Blend Sharpness = 8の場合です。

f:id:kazuhironagai77:20220131004518p:plain

Blend Sharpness = 64の場合です。

f:id:kazuhironagai77:20220131004535p:plain

Blend部分が小さくなっています。

3.3 Triplanar Projection Improvements - Shader Graph Basics - Episode 29 [2]を勉強して

Ben Cloward 先生のTutorialはどれも素晴らしいですがこのProjectionシリーズは群を抜いて凄いです。

ProjectionシリーズのTutorialを全部、勉強し終わったらもう一回復習してまとめ直します。

以上です。

4.Prologueの作成

先週から特に新しいIdeaもないので先週書いた絵をWidgetで紙芝居にしてみます。

4.1 紙芝居をWidgetで作成する

結構、WidgetのtextのPropertyの設定を忘れています。文章がTextからはみ出したりしてました。

取りあえずこんな感じで出来ました。

f:id:kazuhironagai77:20220131004608p:plain

読みましたボタンを押すと次のSlideと文章が表示されます。

f:id:kazuhironagai77:20220131004622p:plain

f:id:kazuhironagai77:20220131004630p:plain

f:id:kazuhironagai77:20220131004637p:plain

f:id:kazuhironagai77:20220131004644p:plain

f:id:kazuhironagai77:20220131004652p:plain

f:id:kazuhironagai77:20220131004701p:plain

かなり推敲が必要なのは分かりました。

4.2 Widgetの作成方法について

先週と先々週、勉強したDrag and DropにしてもWidgetの機能は簡単そうで結構奥が深いです。

何処かにWidgetの機能だけまとめたTutorialはないでしょうか。

後、WidgetってBPの勉強に最適だと思っています。

UEの公式でも良く言っていますが、Programmingが出来なくてもBPを使用すればUEが使用出来るって、間違っていると思っています。そりゃC++よりは簡単かもしれませんがBPだって立派なProgramming言語ですよ。しっかり、正しく勉強しないと使いこなせるようにはならないです。

それで思っているのがVisual Novelの作成です。UEでwidgetだけを使用してVisual Novelを作成するんです。

これってかなりBPの使用方法も学べるし、Widgetについても学べて一石二鳥の勉強法だと思います。

何とかこの分野を掘り下げて、初心者でもUEを学べる取っ掛かりにしたいです。

5.NPCAIを作成する

5.1 先週のBug出しをする

先週、全ての村人のNPCをdynamic にSpawnするようにしました。

Bugがあるかもしれないのでチェックします。

<村長>

f:id:kazuhironagai77:20220131004742p:plain

村長ですね。

f:id:kazuhironagai77:20220131004801p:plain

会話も普通に出来ます。

f:id:kazuhironagai77:20220131004815p:plain

夜になったら消えました。散歩や伸びも普通にしています。

<村長の腰巾着>

f:id:kazuhironagai77:20220131004836p:plain

サイズが小さいですが動きに不自然さはありません。

f:id:kazuhironagai77:20220131004912p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131004927p:plain

夜になったら消えました。

問題ないです。

<村長の娘>

f:id:kazuhironagai77:20220131004951p:plain

村長の娘です。

動きは自然です。

f:id:kazuhironagai77:20220131005008p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005024p:plain

夜になったら消えました。

このキャラは夜も存在させたいですね。

<商売人>

f:id:kazuhironagai77:20220131005044p:plain

このキャラの動きも問題ないです。

f:id:kazuhironagai77:20220131005104p:plain

会話も普通に出来ます。

f:id:kazuhironagai77:20220131005119p:plain

夜になったら消えます。

この商売人とキノコ採りが好きな老人のセリフがヒントになって、Playerは武器を買うお金を得るために山を登る予定になっています。

どの位のヒントを与えるべきかはまだ決めていません。

<元戦士>

f:id:kazuhironagai77:20220131005142p:plain

柵に向かって突っ立っていたのであれ、動きがオカシイのかと思いましたが、その後は普通に動いていました。

f:id:kazuhironagai77:20220131005159p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005215p:plain

夜になると消えました。

このキャラも夜も居てほしいです。元戦士なので夜は村の安全のために巡回しているとかだとカッコイイです。

<詩人の卵>

f:id:kazuhironagai77:20220131005230p:plain

動きに問題はないです。

やっぱりSizeを統一したら伸びをしても不自然じゃないです。

f:id:kazuhironagai77:20220131005253p:plain

会話用のイラストと3D モデルが違い過ぎますが、それは直せないので無視します。

会話は普通に出来ます。

f:id:kazuhironagai77:20220131005310p:plain

夜になったら消えました。

この詩人の卵にどんな役目を与えるのか、まだ決まっていません。

今はあんまり関係のない話をさせています。

<山登りが好きな老人>

f:id:kazuhironagai77:20220131005334p:plain

普通に動いています。

f:id:kazuhironagai77:20220131005353p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005410p:plain

夜になると消えました。

今の会話の内容では特に山に登ろうとは思わないですね。後で改良する必要があります。

<天気予報の人>

f:id:kazuhironagai77:20220131005430p:plain

動きに問題はないです。

f:id:kazuhironagai77:20220131005449p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005506p:plain

夜になったら消えました。

このNPCには特別な役割は考えていません。

単なる数合わせです。

<占い師>

f:id:kazuhironagai77:20220131005528p:plain

動きは普通です。

f:id:kazuhironagai77:20220131005546p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005604p:plain

夜は消えました。

うーん。占い師には特別な役割を与えたいんですがまだ思い付きません。

この章におけるPlayerのすべき事をほのめかすべきでしょうね。

<魔法研究家>

f:id:kazuhironagai77:20220131005626p:plain

普通に動いています。

f:id:kazuhironagai77:20220131005646p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005702p:plain

夜には消えました。

法研究家はPlayerにこの世界の魔法に関する知識を与える重要なNPCです。

この村では魔法に関するどんな情報をPlayerにあたえるのかについては考えていません。

<村の老人>

f:id:kazuhironagai77:20220131005723p:plain

この老人はNav Meshの外側に配置されているので動きません。

f:id:kazuhironagai77:20220131005742p:plain

会話は出来ます。

f:id:kazuhironagai77:20220131005758p:plain

夜になったら消えます。

この老人には村の解説を担当させようかと思います。しかし村長も村の解説をしています。役割分担が必要になりますね。

<村の保安官>

f:id:kazuhironagai77:20220131005819p:plain

こんなに大きくてもSizeが等倍なら動きに違和感はないです。

普通に動いています。

f:id:kazuhironagai77:20220131005852p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131005906p:plain

夜になると消えました。

村の保安官なので夜も巡回してほしいです。

<ハンター>

f:id:kazuhironagai77:20220131005928p:plain

Hunterは沢山いて一人に話しかけると全員が反応します。

特にオカシクは感じませんでした。

いろんなSizeのHunterがいますがそれぞれの動きは自然です。

f:id:kazuhironagai77:20220131005946p:plain

会話も普通に出来ます。

f:id:kazuhironagai77:20220131010002p:plain

夜には消えます。

Hunter達は夜こそ何かしてほしいです。

<旅人>

f:id:kazuhironagai77:20220131010022p:plain

普通に動いています。

f:id:kazuhironagai77:20220131010040p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131010101p:plain

夜は消えます。

旅人は金の切符のありかを知っている秘密の人物です。

何故かPlayerの行く先々に現れます。その正体は物語の最後に明かされます。

<科学者の卵>

f:id:kazuhironagai77:20220131010118p:plain

普通に動いています。

f:id:kazuhironagai77:20220131010148p:plain

会話も出来ます。

f:id:kazuhironagai77:20220131010202p:plain

夜は消えます。

今は科学の芽生えになる様な疑問をPlayerに発するNPCにしています。

一応、Europeの中世風の世界なので科学の芽生えを感じる会話をそこかしこに入れたいです。

私が考える科学的な思考とは、

  • 定性ではなく定量的な考え
  • 再現性があるが数学のように証明は出来ない

の2つを満たしている事です。山本義隆氏の「熱学思想の史的展開」や「一六世紀文化革命」などの思想の香りを入れたいです。

因みに、2番目の科学の定義である「再現性があるが数学のように証明は出来ない」は、私がいた研究室の教授が生徒から「科学の定義って何ですか?」って、質問された時に真っ先に答えた解答です。これに近い内容が確か山本義隆氏の「熱学思想の史的展開」か「一六世紀文化革命」のアボガドロ数の発見の辺りで書かれていた記憶があります。

その教授はアメリカの最も優秀な大学で26歳でComputer scienceのPh.Dをとった生え抜きの天才研究者なんですが、そういう本場本流で勉強した人と会話する時って、山本義隆氏の著作に出て来る科学者たちがそのまま目の前で生き返ったような錯覚を起こさせる時があります。

科学者の卵は特に物語には係っては来ません。

あるいは、物理や数学の問題をPlayerに出したりします。解けたら褒美をくれるNPCに変えるかもしれません。

こっちは促成で現世感が凄いのであんまり好きではないです。

<政治好きのおっちゃん>

f:id:kazuhironagai77:20220131010235p:plain

動きには問題ありません。

f:id:kazuhironagai77:20220131010257p:plain

会話も出来ます。

このおじさんは太っているモデルが良かったんですが、適切なのがなかったです。

f:id:kazuhironagai77:20220131010315p:plain

夜は消えます。

このおじさんは国の政治の噂話ばかりする予定です。

NPCのBugのチェックのまとめ>

これで一応全部の村のNPCのチェックは終わりました。

会話を直す必要がありますが、Programming的な問題はないようです。

5.2 夜のNPCについての検証

<案1:  同じNPCの内、夜でも消えないNPCを作る>

これは作るのは簡単です。NPC_Person BPにBoolean変数を一個追加すれば良いだけです。

f:id:kazuhironagai77:20220131010355p:plain

NPC_Spawn DataにもBoolean変数を追加する必要があります。

f:id:kazuhironagai77:20220131010413p:plain

f:id:kazuhironagai77:20220131010422p:plain

そして以下の部分のData Tableも変更します。

f:id:kazuhironagai77:20220131010439p:plain

こっちは簡単ですね。

<案2 : 夜用の全く別のNPCを作成する>

昼と夜は全く違う動きをするNPCを作成する場合、こっちの方が作り易い気がしています。

ハンターたちは夜は村の入り口に立って警護しているようにしたいです。

ただしこの場合、セリフの設定を考える必要が出て来ますね。

NPCのセリフの仕組みを復習します。

色々見ましたが、

f:id:kazuhironagai77:20220131010512p:plain

f:id:kazuhironagai77:20220131010520p:plain

にFirstVillage_Nightを追加するのが簡単そうです。

そしてHunger_Welcome Widget

f:id:kazuhironagai77:20220131010539p:plain

会話の部分にFirst Village Nightを追加します。

f:id:kazuhironagai77:20220131010556p:plain

更にFirst Village HunterのData Tableの代わりに

f:id:kazuhironagai77:20220131010617p:plain

f:id:kazuhironagai77:20220131010626p:plain

First Village Night HunterのData Tableを作成します。

うん。

これでいけそうです。

取りあえず今週は実際には作成せず、これらのアイデアを1週間熟成させる事にします。

5.3 Data Tableの元のStructに要素を追加する

Data Tableの元のStructに要素を追加するとData Tableの内容が全部消えてしまった記憶があります。

ただStructを元に作成したArrayのDataがどうなったのかは覚えていません。これだけ確認しておきます。

今、作成しているRPGと同じVersionである4.24でやります。

以下のStructを作成しました。

f:id:kazuhironagai77:20220131010645p:plain

このStructを元にData Tableを作成しました。

f:id:kazuhironagai77:20220131010703p:plain

次にGame InstanceにこのStructのArrayを作成しました。

f:id:kazuhironagai77:20220131010720p:plain

f:id:kazuhironagai77:20220131010729p:plain

これを元にしてテストします。

新しい変数をStructに追加しました。

f:id:kazuhironagai77:20220131010752p:plain

Data Tableの結果です。

f:id:kazuhironagai77:20220131010811p:plain

普通に要素が増えているだけでDataが消えたりする事はないですね。

Game Instanceに作成したこのStructのArrayです。

f:id:kazuhironagai77:20220131010830p:plain

こっちもDataが消えるなんて事は起きていません。

うーん。

どうやら杞憂でした。まあ確認出来たのでこれはこれで良いです。

5.4  Event発生におけるNPCのセリフの変化

これのやり方も考える必要がありました。

Game Instanceに新しい変数、Chapterみたいなのを作成してそのChapter毎で、NPCのセリフを変更するようにします。

それよりEventのストーリーを考える必要がありますね。

6.他のMapの作成

今週は、NPCのAIの作成でコードを書く必要がなくなったので時間が余ってしまいました。ので余った時間で他のMapの作成についての調査をする事にします。

Level Designの基礎はMap1とLandscape4の作成で大体理解しましたが、今度作成する時はOpen Worldで作成してPlayerが行ける箇所を限定するやり方にします。一々小さいMapとSub Levelを作成してもあんまり見た目が良くなったりLoadが楽になったりする事が確認出来なかったからです。

更に空飛んで移動するにしても、Open Mapを作成した方が色々な所に飛べます。

しかし今回のRPGは既に小さなLevelを何個も作成する計画で作り始めてしまったので途中で止めるわけにはいきません。

そこで今、無料で使用出来るMapを調べてそれを追加してしまうのかどうかと思っています。

ので今週は無料のMapを調べる事にします。

6.1 Winter Forest Setについて

f:id:kazuhironagai77:20220131010909p:plain

雪国のMapの作成にこれそのまま使用出来ないか見てみます。

f:id:kazuhironagai77:20220131010923p:plain

足跡は付いていないですね。

f:id:kazuhironagai77:20220131010943p:plain

付属のAssetです。

f:id:kazuhironagai77:20220131011000p:plain

雪が積もった木は良いですね。

f:id:kazuhironagai77:20220131011024p:plain

Materialの種類は結構あります。

f:id:kazuhironagai77:20220131011042p:plain

Landscapeに使用しているMaterialはこれでした。

f:id:kazuhironagai77:20220131011056p:plain

実装を見てみます。

f:id:kazuhironagai77:20220131011112p:plain

ここがPointですね。

f:id:kazuhironagai77:20220131011126p:plain

このLayerをどうやってLandscapeで分けているでしょうね。

LandscapeのPaintをみると以下の様な設定になっています。

f:id:kazuhironagai77:20220131011142p:plain

うーん。この辺の設定の仕方を忘れてしまいました。

ちょっと復習する必要がありますね。

でもちょっと復習したら使えそうです。

6.2 Stylized Desert Environmentについて

砂漠の作成ですが、

f:id:kazuhironagai77:20220131011205p:plain

このMapをそのまま、もしくは部分的に使用出来ないか調査します。

f:id:kazuhironagai77:20220131011223p:plain

Landscapeに使用しているMaterialを調べます。

f:id:kazuhironagai77:20220131011453p:plain

これはMaterial Instanceで元のMaterialはこれでした。

f:id:kazuhironagai77:20220131011510p:plain

実装です。

f:id:kazuhironagai77:20220131011529p:plain

うーん。パッと見た感じはそんなに複雑な気はしませんね。

f:id:kazuhironagai77:20220131011545p:plain

かなり上から覗いて見ましたがタイルが繰り返している感じはないです。

砂埃のVFXを追加すれば砂漠のMaterialは使用出来そうですね。

6.3 Multistory Dungeonsについて

ついでにDungeonも調べて見ます。

f:id:kazuhironagai77:20220131011614p:plain

中身を見てみます。

f:id:kazuhironagai77:20220131011630p:plain

f:id:kazuhironagai77:20220131011646p:plain

凄すぎます。

Effectです。

f:id:kazuhironagai77:20220131011752p:plain

Cascadeで作成されていますね。

f:id:kazuhironagai77:20220131011818p:plain

Materialです。

f:id:kazuhironagai77:20220131011838p:plain

これはそのまま使用してDungeonの建築部分だけを作成する事にします。

6.4 その他のAsset

うーん。

FreeのAssetをMarketで見ましたが、まだ沢山使用出来そうなのがあります。

村のNPCのAIの作成については既に完成していますし、夜に生成する実装やGameのEventが発生したらセリフが変わるのはPrologueやRPGのStoryが完成しないと作れない部分があります。来週からは別なLevelの作成について勉強を始める事にします。

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

7.1  先攻が選んだMonsterを見えないようにする

先週、最後まで作ってから気が付いた以下のBugを直します。

f:id:kazuhironagai77:20220131011911p:plain

Monsterの召喚はLevel BPから実装されています。

f:id:kazuhironagai77:20220131011927p:plain

この部分です。

ここで先攻がMonsterを召喚する場合はFakeのMonsterを召喚出来るようにします。

<Fake Monster BPの作成>

Monster BPにFakeのMonsterを追加する場合、ATKやHPの決定をする必要があり面倒になります。とは言っても、単なるActorやEffectを表示すると後々の管理が面倒になる可能性もあります。のでFake Monster用のBPクラスを一個作成する事にします。

作りました。

f:id:kazuhironagai77:20220131011948p:plain

Actorクラスから作成しました。

f:id:kazuhironagai77:20220131012004p:plain

Imageです。銅の球から黒い煙が出ています。

黒い煙のEffectは付属のParticle SystemのP_Steam_Litを改良して作成しました。

f:id:kazuhironagai77:20220131012035p:plain

何で毎週Niagara の勉強をしているのにCascadeを使用するんだ。と言われそうですが、一から作成するのは面倒なのでCascadeを使ってしまいました。

ただどのModuleをいじればParticleの色を変更出来るとか、Particleの速度や加速度の変更したい時はどのModuleをいじれば良いのかなどは、見ただけで直ぐ理解出来たので、Niagaraの勉強が全く無駄になった訳ではないです。

実際のMapに配置すると以下のようになります。

f:id:kazuhironagai77:20220131012105p:plain

ATK値もHP値もありません。

このFake Monster BPを召喚するようにします。

<Fake Monster BPの召喚>

Playerが先攻の時の実装です。

f:id:kazuhironagai77:20220131012124p:plain

Spawn Fake Monster関数の中身です。

f:id:kazuhironagai77:20220131012138p:plain

Monsterが先攻の時も同様に作成します。

f:id:kazuhironagai77:20220131012150p:plain

テストします。

敵が先攻でした。

f:id:kazuhironagai77:20220131012207p:plain

敵のMonsterは表示されないで代わりにFake Monsterが表示されています。

今度はPlayerが先攻の場合です。

f:id:kazuhironagai77:20220131012255p:plain

召喚するMonsterを選んで決定を押します。

f:id:kazuhironagai77:20220131012325p:plain

召喚するMonsterは既に決定していますが、Level上にはFake Monsterが表示されています。

<Fake Monster BPの正体を明かす>

Fake Monsterの召喚の後で、後攻がMonsterを選択し、召喚します。そしたらFake Monsterを消して先攻が選択したMonsterを表示するようにします。

これはそのためのEventを一個作成した方が実装は楽になるでしょう。

f:id:kazuhironagai77:20220131012401p:plain

このEventは後攻がMonsterを召喚し終わったら呼ばれます。

このEventやる事は2つです。

  • Monsterの正体を現す専用のWidgetの表示
  • Monsterの正体を現す専用のEvent Dispatcherを呼ぶ

この2つを実行するためには専用のWidgetとEvent Dispatcherの作成が必要です。それをまず作成します。

Widgetです。

f:id:kazuhironagai77:20220131012428p:plain

f:id:kazuhironagai77:20220131012436p:plain

Dispatcherです。

f:id:kazuhironagai77:20220131012452p:plain

このDispatcherはLevel BPでBindして先攻の魔術師が呼び出したFake Monsterを消して、本当のMonsterを呼ぶためのものです。

このDispatcherの実装を先にする事にします。

f:id:kazuhironagai77:20220131012524p:plain

しました。

f:id:kazuhironagai77:20220131012546p:plain

これで先攻の魔術師が呼び出したFake Monsterを消して、本当のMonsterが召喚されます。

それでは先程のGame ModeのEvent Monster Revealedの実装に戻ります。

f:id:kazuhironagai77:20220131012600p:plain

Monsterの正体を現す専用のWidgetを表示して、今実装したMonsterの正体を現す専用のEvent Dispatcherを呼びました。

このEventは後攻の魔術師がMonsterを召喚した後に呼ぶ必要があります。

今度はそこを実装します。

Playerが後攻だった時です。

f:id:kazuhironagai77:20220131012621p:plain

f:id:kazuhironagai77:20220131012627p:plain

Monsterが後攻だった時です。

f:id:kazuhironagai77:20220131012702p:plain

f:id:kazuhironagai77:20220131012712p:plain

最後にこのEventが終了した時に、次のEventを呼ぶ必要があります。

Widgetから呼ぶ事にします。次のEventを呼ぶ時はこのWidgetを破壊する必要がありますが、Widget内から実装するとそれらを実行するのが非常に簡単だからです。

f:id:kazuhironagai77:20220131012732p:plain

以下の様に実装しました。

f:id:kazuhironagai77:20220131012751p:plain

Event で実装しています。

このEventは当然ですが全てのMonsterの召喚が終わった後で呼ぶ必要があります。のでLevel BPの

f:id:kazuhironagai77:20220131012823p:plain

の最後で呼ぶ事にしました。

f:id:kazuhironagai77:20220131012839p:plain

テストします。

後攻でした。

f:id:kazuhironagai77:20220131012858p:plain

敵の魔術師がMonsterを召喚しました。

Monsterの正体は不明です。

f:id:kazuhironagai77:20220131012921p:plain

こっちの召喚するMonsterを決定しました。

こちらのMonsterが召喚された後、敵のMonsterの正体が明らかになりました。

f:id:kazuhironagai77:20220131012940p:plain

その後、戦闘になり負けてしまいました。

f:id:kazuhironagai77:20220131013000p:plain

先攻の場合です。

f:id:kazuhironagai77:20220131013026p:plain

召喚するMonsterを選択します。

Fake Monsterが召喚されました。

f:id:kazuhironagai77:20220131013048p:plain

相手の魔術師がMonsterを召喚した後でこちらのMonsterの正体が明らかになりました。

その後、戦闘になりました。

f:id:kazuhironagai77:20220131013108p:plain

今度は勝ちました。

f:id:kazuhironagai77:20220131013130p:plain

出来ていますね。

7.2 Naming Conventionを直す

先週、公式のDocumentのNaming Conventionを参考にして

f:id:kazuhironagai77:20220131013155p:plain

Widget のPrefixをWBPに変更しました。

f:id:kazuhironagai77:20220131013208p:plain

が、これって良く考えるとBPしかないのにわざわざBPを追加しています。

その辺であんまり信用出来ない気がしてきたので変更する事にします。

WidgetはW_にします。

f:id:kazuhironagai77:20220131013223p:plain

直しました。

直したんですが、この内の2つはWidgetの名称にWidgetが入っていて、自らスパゲッティコードを作成にいくスタイルなのかと言うくらい混乱する名称なのでこの2つの名称もついでに直しておきます。

f:id:kazuhironagai77:20220131013238p:plain

7.3 敵の魔術師の名称を一致させる

実はこっからが本番で、僅か3週間で混乱を極めてしまった敵側の名称問題を解決します。

敵、味方を問わず召喚して戦う者をMonsterと呼ぶ事にしたのに、敵の魔術師もずっとMonsterと呼んでいました。その結果、Monster Summon Monsterのようなわけわからん名称のクラスやEventが大量発生してしまい、どう整理していいのか分からなくなってしまいました。

味方の魔術師はPlayerとある程度一貫して読んでいるので、ここはPlayerに統一します。

次に敵の魔術師ですが、Playerに対する名称だとAIかなとも思ったんですが、対戦するのなら別にAIだけじゃなくて対人の場合もあるので、ここは対戦相手と言う意味でOpponentとします。

  • 味方の魔術師:Player
  • 敵の魔術師:Opponent
  • 召喚される魔物:Monster

で統一します。

まずWidgetを直しました。

f:id:kazuhironagai77:20220131013302p:plain

f:id:kazuhironagai77:20220131013308p:plain

次にGame ModeのEventの名称を直しました。

f:id:kazuhironagai77:20220131013329p:plain

最後にActorクラスを直しました。

f:id:kazuhironagai77:20220131013349p:plain

これで全部直したはずです。

テストしてきちんと動くか確認します。

あれ。Errorが起きてUE4 Editorが動かなくなってしまいました。

もう一度起動させてテストしたら何も問題なかったです。

ああ、びっくりした。

以上です。

8. UE5Naniteの勉強

8.1 Unreal Engine 5 Tutorial - Create Nanite Meshes [3] を勉強する

通常のStatic MeshとしてImportしたMeshをNaniteに変換する方法が説明されていました。

やってみます。

まずBridgeから岩のStatic MeshをImportします。Tutorialによると最初からNaniteとしてImportする方法もあるそうですが、その辺のやり方の説明はなかったです。Tutorialでは既にDownloadしたStatic Meshから始まっていました。

すっかりBridgeからのImport方法を忘れてしまって結構苦労してTutorialで使用している岩に似たStatic MeshをImportしました。

UE5では以下に示した箇所からBridgeに飛べる事をすっかり忘れていました。

f:id:kazuhironagai77:20220131013423p:plain

LauncherからBridgeのPluginを最新版にUp-dateして下さいと表示されたので、その表示をClickしたらLauncherが開きましたがその後どうすれば良いのか分かりません。のでこの忠告は取りあえず無視します。

適当にいじっていたら以下のStatic MeshがDownloadされたのでこれを使用する事にします。

f:id:kazuhironagai77:20220131013442p:plain

f:id:kazuhironagai77:20220131013451p:plain

前にBridgeからImportした時はTextureのサイズとか指定出来た気がしたのですが、良く分かりません。BridgeからのImport方法については後で勉強し直す事にします。

早速Static Meshを開いて見ます。

f:id:kazuhironagai77:20220131013507p:plain

うーん。

良く分からない。Materialを見てみます。

f:id:kazuhironagai77:20220131013533p:plain

これはMaterial Instanceでした。

親のMaterialを見ます。

f:id:kazuhironagai77:20220131013547p:plain

f:id:kazuhironagai77:20220131013553p:plain

何これ?

まずこの部分の設定方法が分かりません。

f:id:kazuhironagai77:20220131013613p:plain

何でResult ノードが以下の様な形をしていないのでしょうか?

f:id:kazuhironagai77:20220131013629p:plain

今回はここが勉強のPointでないのでこの辺りは後で勉強する事にして先に進みます。

Static Meshを開き以下に示したNanite SettingsのEnabledにチェックを入れてApply Changesをクリックします。

f:id:kazuhironagai77:20220131013648p:plain

これでこのStatic MeshはNaniteになったんでしょうか?

確認します。

以下の設定からTriangleを選択します。

f:id:kazuhironagai77:20220131013705p:plain

結果です。

f:id:kazuhironagai77:20220131013722p:plain

おお。これはどう見ても動画などで見るNaniteのTriangleです。

初めて自分でNaniteを作成しました。

カメラを近づけてみました。

f:id:kazuhironagai77:20220131013737p:plain

カメラが近づいたら三角の部分がもっと細かくなると思ったんですが変わらないです。

うーん。良く分からないです。

f:id:kazuhironagai77:20220131013752p:plain

Tutorialでもグリグリカメラを動かしていましたが三角の大きさは変化していませんでした。そういうものみたいです。

更に驚いたのがMesh表示にしたらNaniteに変更したStatic Meshが写っていない事です。

f:id:kazuhironagai77:20220131013808p:plain

Naniteの三角の表示はMeshじゃないって事なんでしょうか?

一応、このTutorialではNanite Meshと言う呼び名でこの三角を呼んでいますね。

次に以下の設定についてです。

f:id:kazuhironagai77:20220131013822p:plain

Tutorialの話を聞いているとCollisionやRay Tracingなどに使用されるProxyなMeshの生成に関する設定のようです。

Position PrecisionはAutoにセットしておけば大体の場合は適切に対応してくれるそうです。

Proxy Triangle Percentですが2000以下の時は関係ないそうです。

f:id:kazuhironagai77:20220131013842p:plain

げ。ぴったり2000じゃないか。

英語でLess than とかMore thanって言う時って面倒なので以下とか以上と訳していますが、実際はその値は含まないんです。例えばlower than 2000といったら正確には2000未満と言う意味になります。因みに、英語で2000以下と言う時はLess than and equal toといいます。

と言う事はギリギリ私が選んだStatic Meshには影響があるって事じゃないですか。

どうすれば良いの?

分かりました。Meshが2000以下の時はそもそもProxy Triangle を作成しないそうです。2000以上になって初めてProxy Triangleを作成するそうです。その場合、どれくらいの割合でProxy Triangle を作成しますかと言う事をここで指定するみたいです。

TutorialではLess than 2000ならProxy Triangleは作成されないと言った後でMore than 2000 ならProxy Triangleは作成されると言っています。じゃ2000ぴったしはどうなの?

と聞きたくなりますが、日本語の以下、未満、そして以上の使い方みたく理系じゃない人はそんなに厳密に運用してないのかもしれません。

大体2000位からProxy Triangleが適応されるみたいと覚えておく事にします。

この後でNaniteを使用すべきMeshと使用すべきでないMeshについての説明があります。

結構分かり易く説明されていたので以下にまとめます。

<Naniteを使用すべき>

  • Level上に配置するStatic MeshOcclusionがあり沢山のInstanceを使用している。

<Naniteを使用すべきでない>

  • Sky Sphereのような大きなMeshを使用して、Occlusion がない。

以上でした。

今週はNaniteの勉強はこれで終わりにします。来週からもう少し深堀する事にします。

9.まとめと感想

今週は、あんまり頭を使う事はなかったんですが、量が膨大になってしまい上手く整理できなくなってしまいました。

このままゴチャゴチャやっても無駄な事をやりそうな気がしてきたので強制的に終了します。来週まで一週間かけて頭の中を整理します。

10.参照(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] Cloward, B. [Ben Cloward]. (2022, January 13). Triplanar Projection Improvements - Shader Graph Basics - Episode 29 [Video]. YouTube. https://www.youtube.com/watch?v=tsE7Tqlv8DQ&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=29

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