<前文>
<Game Plannerって何をする人なの?>
先週、やっとGame Plannerが本当は何をする人達なのかが分かって来ました。
そりゃ「Game PlannerはGameをDesignする人でしょう」と即答されそうで、しかもその答えは合っているんですが、素人が紙に書く「俺の考えた最高のGame」とは全く違うんです。その何が違うのかについて今週の前文はまとめます。
Computer GameはProgrammingで書かれています。のでProgrammingで出来ない事は作れません。当たり前と思われるかもしれませんがこれが凄い重要です。
Computer GameはProgrammingで書かれていて、それ故にProgrammingで出来ない事は作れないにも関わらず、Game をdesignするGame PlannerがProgrammingを知らないでGame をdesign出来るのか?と言う疑問ってほとんどの人が持たないですよね。
私が日本語のGame Plannerの本を何冊か読みましたが、その人達がどれくらいのProgrammingが出来るのかについて書かれてる箇所は皆無でした。
これはGame をdesignするにはProgrammingの能力は必要ないとみんなから思われている証拠です。
でもこれってオカシイですよね。
車の設計をする人が、機械工学や電子/電気工学の知識なしで設計なんで出来ないです。当たり前です。なのに何でComputer Gameはそれが出来ると思われているんですかね。
機械工学や電子/電気工学の知識のない人が「ランドセルの後ろに羽をつけて飛んで学校に通学出来たら最高だ。何で自動車会社はそれを作らないんだ。」って怒ったらこいつ頭オカシイって思われますよね。
でもComputer Gameではそうは思われないんです。
Game Designの世界では(少なくとも世間一般では、)「ランドセルの後ろに羽をつけて飛んで学校に通学出来たら最高だ。」的な意見が幅を利かせていて、Programmerの立場から現状の技術で何が出来て何が出来ないのかについての発言が重要に思われる事はありません。
それが違うと言う事なんです。
だから実際のGame PlannerはProgrammingに詳しくて、現状のSoftware技術では何が出来て、何が出来ないのか良く分かっているはずです。その上でそれらの技術をこう組み合わせたらこんな新しい事が出来るな。とか新しい技術が○○大学で開発されHolly Woodで使用されていたけど、あれはComputer Gameでも使えそうだな。みたいな事を理解した上で、実際のGameのDesignを作成していた訳です。
それは、素人目には「ランドセルの後ろに羽をつけて飛んで学校に通学出来たら最高だ。」と同じ意見に聞こえますが、その裏には確実に作れる技術的な裏付けがある訳です。
これを理解して初めて次の重要な質問に移れます。
<素人がGame PlannerとしてGameのデザインをするにはどうしたら良いのか?>
無理なんです。そんな事は初めから。
素人がGameを作成するとなると、そんなProgrammingの専門家で全てのGameに使用されているProgrammingの技術に精通している人から見たら失笑ものの実現不可能なDesignしか出来ません。
しかもインディゲームの作成なんかだと、そんな事を言ってくれる親切なProgrammingの専門家も周りにはいませんから見切り発車でデサインして結局完成しないで終りになります。
こう書くと身も蓋もない言い方になりますが事実なのでしょうがないです。
魚釣りに撒き餌ってあるじゃないですか?
あれって無駄だと思いませんか?針がついていない餌を撒く訳ですから。でも実際はそれによって周りの魚が半狂乱になって、何匹かの魚は針のある餌にも食いついてくれる訳です。
これと同じ事をGame PlannerならProgramming出来なくてもなれます。と煽っている人達はやっているんじゃないでしょうか?個人的にはそう感じます。
針にかかる魚は高額なお金を払う…。いや皆まで言うのは止めておきます。
<実際のGame Designに必要な知識>
だから本当のGame Planerは、実際のGame Designに必要なProgrammingを総て知っている必要があります。そのための知識なんですが、もう無限に存在していて一生勉強しないといけません。
しかし世の中にはGame Engineという便利なものが有りまして、そのGame Engineの目的に合致したタイプのGameを作成するに限っては、そのEngineの使用方法を覚えれば最低ラインの知識は身に付くようになっている訳です。
そうは言ってもそのGame Engineの使用方法の最低限のLevelを理解するだけでも膨大な量があります。
それをここに簡単にまとめようと思います。
ただし、私は独学でRPGの作成をUE4を使用してしてるだけなのでその範囲で必要だった内容しか書けません。MMOのように多人数でAccessしたりNetで対戦したりするような機能については全く知らないのでそれらについては更に勉強する必要があります。
<<Level Design>>
UEでは一回にLoadする全てをLevelという概念で管理しています。実際はこの中にSub Levelを作成して更に細かいLoadをしたり一部のみをSeamlessでLoadしたりする事も可能ですが、基本的には一個のLevel上に世界の全てが存在しています。この世界そのものを作成するのがLevel Designです。
このLevelを作成する方法を勉強する必要があります。
正し名前が示す通り、ほとんどが山や平原をDesignしたり予め作成されている家などの建築物を配置したりするなどのDesignが主な作業です。ProgrammingのSkillはMaterialを独自に作成しない限りそんなに高度な技術は要求されません。覚える事の8割位はUEに元々備わっているToolの使用方法です。
RPGで草原、砂漠、雪山、火山、迷宮などを登場させたい場合はそれらを作成するための特別なLevel Designの勉強が必要になります。
私は草原を何カ月も掛けて作成しましたが、草原の作成だけでもう疲れてしまいました。ProgrammerがUE4でGameを作成する場合は無料で手に入るLevelをそのまま使用した方が良いと思っています。芸術的なセンスがあるわけではないですし、Designerになる訳でもないですから。
よくEnvironmental Artist と言う職種が載っているんですが、この人達の仕事とLevel Designをする人達の違いが私には良く分かりません。
<<3D modelの作成>>
当然、Level上に配置する3Dを作成する必要があります。これはUEには備わっていない機能なので、他のソフトで作成したのをUE4にImportします。ので他のSoftwareの使用方法を学ぶ必要があります。お金の有るGame会社ならMayaを使用して作成するのが普通みたいですが、個人で作成する場合はBlender一択です。なんせ無料ですから。
ここではLevel上に配置するモノの作成だけでなく、Level上でPlayerやAIの指示で動くSkeletal Meshの作成も必要です。更にそのAnimationの作成もです。
Programmingが全く出来ないかつ英語も数学も出来ないけど、どうしてもGameを作成したいと言う人が、もし私にアドバイスを求めてきたら、全力でこの3D modelの専門家になる事を進めます。
Artの能力は必要ですが、3D modelの作成にはProgrammingも数学もほとんどいりません。英語は出来たら得ですが出来なくても何とかなります。
そしてここが大切な所ですが、英語圏では美人の3D modelの作成やアニメ調の3D Modelの作成をする事が色々な事情で難しいんです。大学や研究所でそれをやると客観性がないに対しては研究費は出せないとなって予算が打ち切られてしまうんです。だからもうどうしてもアニメ調の3Dモデルを作成しないといけないとなる場合は絵を用意してその絵をなぞるように3D Modelを作成しています。もし貴方しか作成できない美麗な3D modelやアニメ調の3D Modelがあれば一気に何千万を稼ぐ売れっ子になれる可能性があります。
RenderingやMaterialに関してはProgrammingの知識がかなりいるのでその辺はきっぱり諦めるのも手です。
<<AI>>
Level上に配置したMonsterやNPCはAIを使用して動かします。UE4ではBehavior Treeを使用したAIの作成方法を採用しています。一見複雑ですが、Object Oriented 系のProgrammingでIf節かSwitchを使いこなせるLevelだったら理解出来ます。今流行りの機械学習とか深層学習などの理解は、少なくとも基礎を理解するだけなら必要になる事はありません。
<<戦闘システムの構築>>
RPGの作成には戦闘システムの作成が必要不可欠です。私が今作成しているGameはTurn制なので一から作成する必要がありました。そういう意味では
この教科書は優秀で、ほとんどこの教科書通りに作成しました。当然、Programmingのスキルが要求されます。Unreal Engine 4 Scripting with C++ Cookbookに書かれている内容が理解出来ればこの本の内容で分からない事はないです。
<<UI Design>>
意外に苦労する、そして今も苦労しているのがUI Designです。普通のRPGの作成でSlate を理解する必要はないです。UMGの使用方法を理解するだけで必要最低限の物は作成出来ます。
しかしUIの作成で難しいのはProgrammingよりもデザインです。
あんまりUIのデザインについては語るほど勉強していません。多分ですがWebのUIデサインの本とか参考になると思います。
<<NPCとの会話システムの構築>>
UIの設計で追加で必要なのが会話システム構築です。
私はTypewriter Effectの作成方法は知っていたのですが、面倒だったので今のGameでは作りませんでした。今は凄い後悔してます。文字の表示が速くて表示されている文が読みにくいです。
<<音楽>>
全く分かりません。無料のヤツをそのまま使用しています。
<<シナリオの作成>>
RPGですのでシナリオを作成する必要があります。これはまだ全く手を付けてないのでアドバイスは全くできません。
<<Effectの作成>>
Effectそのものの作成にも結構Programmingの技術と知識が必要なのに更に物理の知識が必要になって来ます。更にEffectの30%位はMaterialそのものの質がかかって来ます。芸術性が要求される分野ですが、結構なProgrammingの知識と物理・数学の知識が要求されます。
最初のGameの作成では無料で手に入るEffectをそのまま使用するのが無難です。
<<Materialの作成>>
Effectの作成やLevel Design、3D Modelの表面の貼り付けなどに使用します。非常に複雑な計算とHLSLやGLSLなどの3d Graphics 用のProgrammingの知識が必要で簡単には理解出来ません。誰かが作成したものを使用するのが無難です。
<<それ以外>>
Packingの仕方やinputの設定、Inventory systemの作成、CharacterのParameterの作成など、それ以外にもいっぱいありますが、細かくなり過ぎるのでそれ以外を全部まとめます。BPが使えれば何とかなると思っています。出来ない事は諦めて出来る部分だけでGameを完成させるのも必要です。
あんまり綺麗にまとまりませんでした。まあしょうがないですね。
それでは今週の勉強を始めます。
<本文>
1.今週の予定
今週もいつも通りやっていきます。
- Niagara: Flower Effect in UE4 Niagara Tutorialの続き
- Material : Content Exampleを見るの続き
- NPCのAIを作成する
- Game Design:ポケモン+HxHの念能力( 戦闘システムの作成)
- Map1のBug直し:武器屋で買える武器の設定の追加
- UE5:naniteの勉強
2.Niagara: Flower Effect in UE4 Niagara Tutorialの続き
先週勉強したCGHOW氏のFlower Effect in UE4 Niagara Tutorial [1] の検証をやっていきます。
2.1 Radial Gradient Exponentialノードの検証
Material 内で使用したRadial Gradient Exponentialノードは前に何回か使用していますが、その実装方法まで見た事はないです。今回は実装方法についても調査します。
まずは3つのCommentから見て行きますか。
<User Sphere Density, avoids center pinch but has absolute edge radius>
うん。これ繋がってないですね。最後のSqrtノードがちぎれています。
使用してないので取りあえずは無視して次に行きます。
<Normal Density>
こっちもClampノードに接続した方は使用してませんね。Exponential Densityノードに接続した方だけ使用しています。
<<Exponential Density>>
Exponential Densityと言うのですからF(x,y) =1/(y^x) のような式で計算しているはずです。
YがDepth、xがDensityもしくはその逆と言う事でしょうか。
このNodeについて調べたんですが解説が見つかりません。
やっと見つけたのがここです。公式のDocumentであるMath Hall Content Examples [2] です。
ここはContent Exampleの内容を説明している章の一部で、Math_Hall mapについて解説しています。その中の一つにありました。
Content Exampleを開いて確認してみます。
これですね。
と書かれているのですがSlide barが動きません。
あ、Simulationだと出来ないみたいです。普通のPlayだと動きました。
後ろに設置してある展示物がDensityの意味を解説していて分かり易いです。
Densityがほぼ0の時です。
Densityが5の時です。
Densityの数字が大きくなるほど不透明になります。
式そのものの解説がほしいですね。
この展示物からではDepthがどんな影響を与えているのかは分かりませんね。
このMapには?ボタンが設置していませんね。と言う事は解説のDocumentもないんでしょうね。
以下のImageを作成しているMaterialの実装も一応チェックしてみました。
これです。
うーん。複雑過ぎて読む気が無くなりますね。
あそうだ。自分で実験してみればいいんだ。
こんな感じです。
まずはDensityの数字を上げます。
Density=5にしました。
不透明になりました。
先程の展示物と同じ結果です。
Density=1に戻してDepthの値を変化させます。
Depth = 1の時です。
Depth = 2の時です。
不透明になりました。特に中心から不透明になるとかは観測されないです。
うーん。正直もうこのノードに対して飽きて来ました。今回はこれ位で終わりにします。
<Inverted Density>
Inverted Densityは先程のCommentのOne Minusの無いVersionです。
<Switchノードを追う>
先程のNormal DensityとInverted DensityがSwitchに繋がってOutputされています。
Radial Gradient ExponentialノードのInputを見るとDensityとInverted Densityがあります。
ここでDensityに値がInputされた時はNormal Densityの値、Inverted Densityに値がInputされた時はInverted Densityの値が使用されるみたいです。
となるとNormal Densityの方に注目すればRadial Gradient Exponentialノード内でどんな計算をしているのかが分かります。
<Normal Density、再び>
以下に示した様にExponential DensityノードのDensityインプットにはRadial Gradient ExponentialノードのDensityの値がそのまま使用されています。
となるとDepthの値が問題です。
Depthの値は、
で計算されています。
色々分からない所がありますが、一個ずつ見て行きましょう。
まずはここです。
この意味が分かりません。
Input UVs(vector2)はMaterial FunctionのInputです。何でTexCoord[0]ノードが予め付いているんでしょうか?このTexCoord[0]の値はInput値が無い場合にDefault値として使用されるのでしょうか?
Input UVs(vector2)のPreviewを見ると
TexCoord[0]ノードの値がそのまま表示されています。その様ですね。
一応、確認します。
以下のMaterial Functionを作成しました。
このMaterial FunctionをMaterialから使用します。
MF_TestのPreviewを見るとエラーになりました。
あれ?
TexCoord[0]ノードを繋ぎました。そしたらErrorが消えました。
Previewの結果はこうです。
うーん。
この結果から推測するとMaterial Function のInputにつないである値はあくまでMaterial FunctionのPreviewのためであり実際にMaterial 内で使用される時は関係ないみたいです。
兎に角、この部分の意味は分かりました。
Inputされた値をそのままパスしているだけです。
因みに、このTutorialでのInputの値はTexCoord[0]+何かです。
TexCoord[0]がパスされたと仮定して計算を進めてもあまり問題はないでしょう。
次にもう一つのInputの値であるCenter PositionとDistanceを計算しています。
Center Positionは何もInputしていません。
この場合は(0.5,0.5)がCenterになる様です。
何でこっちのInputはDefault値が適応されるんでしょうか?
Input のparameterに
Use Preview Value as Defaultがありました。
これをCheckするとPreviewの値をDefaultとして使用出来るみたいです。
Use Preview Value as DefaultをCheckしたら先程Errorが出たMaterial Functionも
ErrorなしでMaterialでPreview出来ました。
かなり勉強になっていますね。
細かいけど大切な機能が次々に解明されています。
Distanceの結果に戻ります。
Center Positionが(0.5,0.5)なので中心が最も黒くそこからGradientに白くなっています。
成程。(0.5,0.5)の点からどれだけ離れているかを計算して同じ位置の値は0、最も離れている位置は1になる訳です。
Texcood[0]の場合、中心の値が(0.5,0.5)なので0になり(0,0)、(0,1.0)、(1.0,0)、(1.0,1.0)の4つの角は最も大きな値になります。
Distanceノードの正確な計算は公式のDocumentのUtility Expressions [3] によるとDistanceの計算は以下の様になっているそうです。
ちょっとこの計算が実際のどの計算を表しているのか分からないですが、単純に(0.5,0.5)からの距離を計算していると解釈します。
次のMultiplyですが1を掛けているだけなので無視します。
その後でInputした半径で割っています。
Previewの半径は0.5なので値が2倍になりその結果白い部分が増えました。
One Minusノードで値を逆にします。
その値をExponential DensityノードのDepthにパスします。
これがRadial Gradient Exponentialノードの実装でした。
<Radial Gradient Exponentialノードの再現>
自分で同じ機能を実装してみました。
結果です。
同じ値をRadial Gradient Exponentialノードに入力した場合です。
同じ様な結果になっていますね。
<Radial Gradient Exponentialノードについてのまとめ>
Radial Gradient Exponentialノードの実装を一通り勉強したんですが、予想以上に理解出来ました。Exponential Densityノードばっかり調べていたので、また粒度(Granularity)がバラバラになってしまったと焦っていたのですが、結果的にはExponential Densityノードの理解がRadial Gradient Exponentialノードを理解するための肝でした。
2.2 Flower Effect in UE4 Niagara Tutorial [1] の検証の続き
<3ColorBlendノード>
これはどっちかと言うと実験した方が分かり易いので実験します。
以下の実装でテストします。
Alpha = 0
Alpha =0.5
Alpha =1
これは想像の通りです。
Alpha = 0.25
Alpha = 0.75
丁度中間の色ですね。
<Opacityに5を掛ける理由>
Opacityは1つまり白い部分を不透明にします。
Opacityの値がこうだと
結果はこうなる。
この白い部分の濃さを5倍にしただけです。
<円に歪みを加える方法の検証>
ここは本当に何をやっているのか分からないです。
先週のBlogを見るとまず以下の実装をやっています。
繋ぐにしても普通、こうじゃないですか?
確認します。
してました。
当然、こういう結果になりますね。
Distanceの値がこうなりました。
途中の計算結果です。
Exponential DensityのPreviewです。
この計算結果を見る限り、NoizeでTexCoord[0]とCenter Positionで作成した円状のGradientが完全に消えてしまって意味ない気がします。
成程。分かりました。それで0.12をかけてNoizeの大きさを約10分の1にしたんですね。
これだとTexCoord[0]とCenter Positionで作成した円状のGradientが残りつつもNoizeの影響も見えるようになっています。
よしここまでは納得しました。
これって何故なんでしょう。
単純に言えばTexCoord[0]に値を追加しているため0.5、0.5が中心より少しだけ小さくなってるからですね。勿論、追加した値はNoizeがあるので全部がそうなるわけではないですが、大体の傾向としてそうなる訳です。
しかし以下の値を掛けた場合は中心は移動しません。
うーん。
計算結果見たら分かりました。左上の値が0になっています。
Textureと掛けた結果を見ても左上は真っ黒で0のままでしょう。
TexCoord[0]と足した結果です。
左上4分の1の値が0になっているので左上に円の中心が移動しないと考えられます。
ただこっちを弄った方がずれを直しやすい気がするんですが。どうなんでしょう?
Tutorialではこの部分の詳しい内容は以下のTutorialで解説しているのでそっちを見てくれと言っています。
うーん。
そうしますか。
でも来週以降ですね。見れるのは。
そうなるとそこまでして見たくはないですね。
<Pannerノードを追加する>
Pannerノードはほとんど初めて使用します。
でも使い方はTexture Sampleに繋げるだけなので簡単なはずです。
Speed Xに0.1を追加しました。
あれ。
消えてしまいました。
凄く調べたらどうやら使用するTextureのTiling Methodは
Wrapじゃないと駄目みたいです。
動くようになりました。
この問題を解決するのに結構時間がかかりました。
2.3 Flower Effect in UE4 Niagara Tutorial [1] の検証:Niagaraの作成について
Niagaraの勉強なのにずっとMaterialと格闘していました。やっとNiagaraに入りました。
<Sorting Mode>
Sorting ModeはRender SectionのSprite RendererのParameterです。
取りあえずCursorを乗せて解説を見ます。
Sorting Modeについてです。
Custom Descendingについてです。
公式のDocumentはNiagara Renderers [4] にありました。
大体の特徴は読んだら理解出来ましたが、一応確認します。
<<None>>
Sortingはなしの状態です。
なしとは言っても後からSpawnした赤いSpriteは常にカメラから見て前にあります。
<<View Depth>>
View Depthです。
解説によればCameraのNear Planeに近ければ近い程、前にSortingされるみたいです。
因みにNear Planeは以下の図の中に示しています。
<<View Distance>>
こっちはカメラまでの距離です。
この距離ではView Depthと同じですね。
思いっきり近づいて取ってみました。
<<View Depth>>
<<View Distance>>
違いは分からないですね。
<<Custom Ascending>>
これは古いSpriteが前に来るので最初以外は必ず緑色が前になりますので区別しやすいです。
<<Custom Descending>>
こっちは新しいSpriteが常に前に出て来るので赤いSpriteが必ず前になります。
Sorting Modeについては理解出来ました。
残りは来週やる事にします。
3.Material : Content Exampleを見るの続き
今週もContent Example の見学はお休みしてBen Cloward先生のTutorialを勉強する事にします。
3.1 Advanced Channel Packing - Shader Graph Basics - Episode 23 [5] を勉強する
<どう勉強するかについて>
まずサラッと見ましたが、かなりの神回で凄い勉強になりそうです。単に呼び込むTextureの数を3つから2つに縮小しているだけですが、適当にやるといろんな間違いを起こします。TextureやMaterialの正しい理解が必要になります。
うーん。どうやって勉強していこうかな。
まず勉強する内容ですが、以下の3つのTextureを
同じ効果を保ちつつ以下の2つのTextureで代用します。
これをやっています。
本来なら自分でもTextureを加工して本当に変化がないか確認しながらやるべきですが、私Textureを加工するためのSoftもやり方も知りません。
Comment欄を見るとやっぱりみんな自分でTextureを作成して確認しながら勉強しています。
Ben Cloward先生はSubstance Designerがお勧めのようです。
これの事ですかね。
無料じゃないのか。
パスします。
RGBAの値を別々に入力する機能があるImage Editorがあれば良いのか、それともTextureを編集する時点でsRGBとかCompressionのやり方とか、拡張子の設定とかまでやらないといけないのかが分かりません。
うーん。やっぱりこういうのを購入する事も検討しないといけない時期なのかもしれませんね。
そうだ。UE4で作成したGameを売ってそのお金で購入すれば良いんだ。これなら赤字になる事もありませんし。
まあ、今回はTextureの編集は見送りですね。
今から勉強したとしてもそれだけで時間取られてしまいますし。
今週は見るだけで勉強する事にします。
<元のtextureの設定の確認など>
これが元のTextureです。
これ見ただけじゃ良く分からないので、UE5に元々入っているMaterialと比較してみます。
どれでも良かったんですがNormal を使用してそうなので以下のMaterialを選びました。
中を開くと実装は以下の様になっていました。
今回の部分とTexture Variationは関係ないのでTexture Variationの箇所は無視します。
一番下の部分も無視します。
大切なのは真ん中のこの部分です。
と思ったらTutorialで使用されているのとそっくりなTextureが3つありました。
このTextureが
Tutorialの言うColor Textureに当たるんでしょうね。
中を開くとこんな感じです。
AにもImageが入っています。
これがOpacity用のImageなんでしょうか?
M_Brick_Clay_Newの方で確認したらHight MapのDataでした。
Hight Mapってこう使うんですね。Bump Offsetノードですか。勉強になりました。
Normal Mapの方です。
いつもNormal Map用のTextureを見て思うのがBのImageが消せないです。
こんな風にBだけ残ります。
TutorialのNormal MapのDataです。
Alphaには何も入っていません。
Mask Textureです。
Tutorialのサンプルは以下の種類のTextureが入っています。
M_Brick_Clay_Newで確認するとRにRoughness、GにAmbient Occlusionが入っているみたいです。
Bには以下のImageが入っていますが
どこにも使用していませんね。
Tutorialでは元の3つのTextureについてはあまり解説していませんが新く作成した2つのTextureについては解説しています。
特にNormal Mapにおいて
Compression SettingにNormal mapがセットされていますが、
この新しいTextureであるNormal Map + Ambient Occlusion or Opacity + Height(optional)は
にセットされています。
しかしNormal Mapを含んでいるのでsRGBはOffのままです。
<通常のTextureをNormal Mapに変換する。Normal MapのxyからNormal Mapのzを計算する>
通常のTextureは0~1の間で色を指定していますが、Normal MapのDataは-1~1の間で値が保持されています。
更にNormal Mapのzのdataも計算で導く必要があります。
以下の方法で計算するそうです。
最初の2倍して1を引くのはTextureのRangeを0~1 から-1~1に変更します。
Normal MapのzのdataはNormal Mapのxとyの値を使用してPythagorean Theorem(ピタゴラスの定理)から導きます。
と言う事は1= x^2 + y^2+ z^2から、z =sqrt( 1- x^2 - y^2)を計算すると考えられます。
その様に予測して上の計算を見ると実際そのように計算しています。
この計算を行えば残りのTextureはそのまま使用出来るそうです。
Tutorialでは以下のようにつないでいます。
<この方法を採用した場合に発生する微妙な品質の低下について>
正し注意しなければならない点もあります。
Normal Map用のTextureを見ると
普通のTextureとして
で保存したNormal Mapです。
Normal Mapとして
で保存した場合です。
YouTube用の撮影用にCompressされた映像からだと、違いは分からないですがTutorialによると少し違うそうです。
この辺は実際に自分でTextureを編集してみないと分からないですね。
むむ。Tutorialでは通常のTexture用のCompression Settingに以下のBC7を使用していました。
うーん。
こっちのCompression Settingとの違いについても調べる必要もありますね。
まあでもどちらもNormal Map用のCompressionではないので何らかの悪い影響が出るのは間違いないですね。
適所適材としてNormal Mapの精度が少しぐらい落ちても問題のない地面とかにはこれを採用して、Character特にCharacterの顔のようなちょっとでもNormal Mapの質が落ちたら悪い影響が出る所は元のやり方でやるみたいな選択が必要だそうです。
<Derive Normal Zノードについて>
後、Normal のzをNormal のxyから計算するのに以下のDerive Normal Zノードを使用すると全部ノードの中でやってくれるそうです。
以上です。
以上ですがCommentの質問が大変勉強になるので幾つかここにまとめます。
<Commentの質問とその解答>
Roughnessの値はAlphaにsRGBとして保持しました。このRoughnessの値は通常のRGBに戻さないで良いのでしょうか?と言う質問です。
それに対して、Ben Cloward先生はsRGBで設定してもAlpha Channelは影響されないでLinerになっているはず。ので直す必要はないはずです。と言っています。
うーん。
勉強になります。
次の質問です。
Alphaのある2つのTextureのDataはAlphaのある3つのTextureよりDisc上のサイズが大きいはずですが、このやり方で本当にTextureのMemoryを少なく出来るでしょうか?
勿論、Textureを2回呼び出すのはTextureを3回呼び出すより速いですが、このやり方だとMemoryは余計に使用する事になるのではないでしょうか?
うげえ。
そんな事まで考えてんの?
これについては色々コメント欄で議論していますが、驚嘆するだけでどれが正しいのかとかどの程度重要なのかについては分かりません。
個人的にはMemoryを多く使う事でPerformanceが落ちるなら問題だけとそうじゃない場合は、別にMemoryを多く使用しても良い気がしますが。どうなんでしょう?
Materialを自分で組むときにはこれぐらい理解しないといけない事を理解した事で満足します。
後、Unityの例でNormal MapのYの向きを直すのを忘れていますよ。と言うコメントが何個かありましたが、これは弘法も筆の誤りでしょう。
以上です。
4.NPCのAIを作成する
今週やる事は2つです。
4.1 走っているNPCを歩かせる
これはMonsterのAIでやったやり方と同じ方法でやれば出来るはずです。
<MonsterのAIの速度の調節方法について>
まずMonsterのAIを確認します。
Service BPであるSetMaxSpeedを使用してMonsterの最大移動速度を調節しています。
実装は以下の通りです。
変数Speedを作成してそれに150をセットしています。
これと同じ事をNPCにも試しましょう。
まずNPC用に歩く速度を指定するServiceを作成します。
実装部はMonster用のSpeedを調整するService、SetMaxSpeedとほぼ同じですがNPC_PersonにCastする所だけが違います。
これをNPC用のBehavior Treeにセットします。
これでNPCは歩いてくれるはずです。
テストします。
歩いています。
ただし地面を滑っているような歩き方です。
<地面を滑っているような歩き方の直し方>
多分、移動する距離が遠いので秒速130cmでは遅くて目的地に着かないのでしょう。目的地を少し近くにします。
NPC用に新しく目的地を選ぶServiceを作成します。
距離を近づけました。
テストします。
うーん。前よりはマシですが、やっぱり変です。
どうも地面がデコボコな所を歩いていると片足が浮いているから滑っているように見えるみたいです。
うーん。
これを入れる必要がある?
これってCreate ProjectなんでProjectの作成時に使用しないといけないのでしょうか。そうだとすると今回は既に無理ですね。
今回はこれ位で我慢しておきます。
4.2 全部のNPCを動かす
色々なBugが発生するのは承知で町全体にNav Mesh Bounds Volumeを配置してNPCを動かしてみます。
こんな感じです。
テストします。
NPCのみんながSlideしています。Animationが適応されていません。
AnimationのAnim ClassにNPC_AnimationBPがセットされていませんでした。
テスト様に一個だけセットします。
確認します。
歩きだしました。
全部のNPCのAnim ClassにNPC_AnimationBPをセットします。
みんな歩き始めました。
止まって虚空を見つめている時間が少し変ですが今週の進捗としては十分です。
5.Game Design:ポケモン+HxHの念能力( 戦闘システムの作成)
5.1 先週決めた手順を実装する
以下の手順を実装します。
Game Mode BP内に実装する事にします。
まずこれらの手順はCustom Eventで管理する事にします。
<Event Choose First>
先攻後攻を決めるCustom Eventです。
Bool変数、IsPlayerFirstに値をセットし、Trueだった場合は、Event Player Decisionを実行します。Falseだった場合はEvent Monster Decisionを実行します。
<Event Player Decision>
Player が何をするのかを決定するCustom Eventです。
具体的に何を決定するのかは複雑なので今は実装しません。
Playerが何をするのかを決定した後です。
<Event Monster Decision>
Event Player DecisionのMonsterバージョンです。
<Event Player Action>
Event Player Decisionで決定した選択を実行します。
実装内容です。
まずEvent Player Decisionで決定した選択を実行します。
次にその結果、戦闘の勝敗が決定したのかを調べます。
もし戦闘が終了した場合はEvent Fight Overを発動します。
それ以外の場合はPlayerが先攻の時は、Event Monster Actionが発動します。
Playerが後攻の時は、戦闘の最初に戻って先攻、後攻を決めます。
<Event Monster Action>
Event Player ActionのMonster版です。
<Event Fight Over>
Playerが勝ったか負けたかを判断します。
<Event Escape>
途中で戦闘を放棄して逃げた場合です。
何をするのかも決めていませんし、何時発動するのかも決めていません。
どのEventを何時呼ぶのかは大体分かりますが、一応したに整理しておきます。
<先攻後攻を決める>
当然、Event Choose Firstを呼びます。
<先攻が次のターンの行動を決める>
先攻がPlayerの場合は、Event Player Decisionを呼びます。
先攻がMonsterの場合は、Event Monster Decisionを呼びます。
<後攻が次のターンの行動を決める>
後攻がPlayerの場合は、Event Player Decisionを呼びます。
後攻がMonsterの場合は、Event Monster Decisionを呼びます。
<先攻が1で決めた行動を実行する>
先攻がPlayerの場合はEvent Player Actionを実行します。
先攻がMonsterの場合はEvent Monster Actionを実行します。
<後攻が2で決めた行動を実行する>
後攻がPlayerの場合はEvent Player Actionを実行します。
後攻がMonsterの場合はEvent Monster Actionを実行します。
<勝負がつくまで1~5を繰り返す>
Event Player ActionのCheck ResultかEvent Monster ActionのCheck Resultで勝負が着いたかどうかを確認します。
勝負が着いていない場合は、Event Choose Firstに戻ります。
<勝利、敗北、逃走のどれかになる>
Event Player ActionのCheck ResultかEvent Monster ActionのCheck Resultで勝負が着いたかどうかを確認します。
勝負が着いた場合は、Event Fight Overを発動します。
Playerが勝利した場合は
Playerが敗北した場合は
を実行します。
PlayerかMonsterが逃走した場合は、
を発動します。
5.2 Widgetを作成する
これだけだとEventが発動しても分からないので仮のWidgetを作成してEventの確認をします。
以下のWidgetを作成しました。
それぞれのWidgetをそれぞれのEventから呼ぶようにします。
更にEventの実装の一部分をWidgetに担当させます。
これで、以下のStageが実行されているかWidgetを通して確認出来ます。
テストします。
開始ボタンを押します。
先攻後攻の決定をするPhaseになりました。
先攻・後攻を決めるためにボタンを押します。
後攻になりました。
相手がどんな攻撃をするのかを決定するPhaseに入りました。
ひたすら待っています。
今度は、私がどんな攻撃をするのかを決定するPhaseに入りました。
私の番です。
まだどんな攻撃が選択出来るのか決めていないので、決定を押して選択を終了します。
相手のActionのPhaseに入りました。
相手が攻撃をして来ました。
PlayerのActionのPhaseに入りました。
自分が攻撃をしています。
勝負が着かなかったのでまあ最初からやり直しです。
戦闘が終わったPhaseです。
負けてしまいました。
勝った時です。
5.3 Game Design:ポケモン+HxHの念能力の再考
こんな感じで、先週考えた戦闘システムの4つのPhaseを実装しました。実装中にもっと単純な戦闘システムを思いつきました。
戦闘は魔術師と魔術師のみにします。
最初のターンです。
<Decision Making>
魔術師は三体のMonsterを互いに召喚します。
<Action>
三体のMonsterは正面のMonsterと戦います。
次のターンです。
<Decision Making>
魔術師は魔法を使用して相手のMonsterを一体、眠らしたり、位置を入れ替えたりします。魔術師が干渉出来るMonsterは一体だけです。
<Action>
魔術師の魔法が作用した状態で、またMonster同士が戦います。
このターンをどちらかのMonsterが全滅するまで繰り返します。
こっちのシステムのMonsterの方がポケモンのような戦闘が始まる前に勝敗が決定する戦略型のGameの面白さを表せる気がします。勿論、魔術の魔法はHxHのような戦闘時に一発逆転出来る戦術型のGameの面白さを表しています。
ので配置しているMonsterをMageに変更しました。
5.4 召喚出来るMonster候補を探す
となると来週は、最初のターンのMonsterの召喚部分の作成を行う事になると思います。
まずMonsterのParameterに関しては先週の考え方でまだいけると思います。
ので今回は、使用出来るMonsterの3D Modelを調べておきます。
<City of Brass Enemies>
<<Archer>>
Archerです。
結構、Monster向きのDesignな気がします。
<<Charger>>
うん。どのCharacterもMonsterとして使用出来ますね。
15体ありますね。どれもMonsterとして使用出来そうですね。
<Desert Dragon>
これは一体だけですね。
<Four Evil Dragons HP>
Dragonが5体ありますね。
ポケモンみたくドラゴンタイプを作るか、火、砂、木タイプにするか悩みますね。翼の無いドラゴンもいますね。
<Skeleton Crew>
魔法使いとして一体使用していますので、残りの4体がMonsterとして使用出来ます。
<Toony_Tiny_RTS_Set>
うーん。これはMonsterには一寸きついかもしれませんね。
魔術師のModelはここから使用しているので残りの3d ModelはMonsterに使用したいですね。
どんなMonsterが魅力的なのかについては全く分かりません。
MonsterのDesign次第なのか、それとも他のMonsterとの関係によってそのMonsterが魅力的になるのか。その辺が良く分かっていないです。
今週はこれ位にしておきます。
6.Map1のBug直し:武器屋で買える武器の設定の追加
今週は武器屋で職業によって買える武器に制限を加えます。
6.1 Enumを調べる
Occupationである弟子、狩人、戦士、騎士、魔術師、そして魔法戦士をEnumで作成しておきたいです。間違えると後々面倒ですから。
今までこのGameでEnumを作成する時は、以下に示したようにC++内で作成していました。
今まではEnumは英語で書いていたので特に問題は感じなかったんですが、今回の職業は最初から日本語です。
うーん。これどうしようかな。
UE4EditorからEnumを作成した場合、日本語でも出来そうなんですが。
調べたら村の名前はUE4EditorからEnumを作成して使用していました。
YourHeroClasses Structの設定を調べるとOccupationのタイプはFStringです。
うーん。
これをEnum Occupationを作成して全部書き直すのは結構大変になりそうです。
よし職業のEnumを作成するのは止めました。
Structを作成する事にします。
武器名のStringとその武器が買える職業の名前が入ったStringの配列で構成されるStructを作成します。武器屋が武器を売るときにはそれを参照します。
StructはUE4C++で作成するか
UE4Editorで作成するか
していて本当はUEC++の方で作成すべき内容なのですが、Compileするのに時間がかかり過ぎるのでUE4Editorで作成する事にします。
以下の様に作成しました。
このStructを利用して武器が売れるかどうかのチェックをします。
6.2 武器を買う時にチェックする
Weapon Widgetです。
Weapon Widgetのここで売れるかどうかのチェックをして適切な職業のみに売る事が出来ます。
あるいはWeapon Shop Widgetの商品の所に
買えない武器は表示しないならここで変更します。
あるいは買えない武器は別なボタンで表示するならここを変更します。
別なボタンを作成してクリックするとこの武器を買える職業はOOだけです。と表示される方が分かり易い気がします。
6.3 作成したStructを利用して変える武器だけボタンを作成する
追加しました。
テストします。
あれ。
一個も武器が表示されません。
あ。先程のStructに職業:弟子を作成するのを忘れていました。
追加します。
もう一回テストします。
あれ。
買えない武器まで表示されています。
これを忘れていました。
もう一回テストします。
今度は出来ています。
他の職業でも試してみます。
先週のBlogを読み直すと
職業はUE4C++で指定しています。
これを直すと色々面倒なので、仮に以下の実装をRPG Game Mode BPのEvent Begin Playに追加する事で他の職業の場合もテストします。
Occupationは狩人になっています。
結果です。
狩人が買える武器だけが表示されています。
戦士の時です。
結果です。
戦士は短剣(小)、短剣(大)も買えるようにするか悩んでいますが、それは後で直せば良いです。
コードが正しく実行されている事が大切です。
騎士です。
指定した武器と防具が表示されています。
魔術師です。
最後に魔法戦士です。
斧とハンマー以外の全ての武器が買えるようになっています。
出来ていますね。
今週はここで一週間寝かせます。
来週続きをやります。
7.UE5:naniteの勉強
今週もNaniteの勉強の続きをやっていきます。
番号は先週の続きと同じにします。
7.7 Nanite Proxy Mesh and Precision Settings
Proxy Meshについてです。
これのSettingはStatic MeshのNanite SettingのPosition PrecisionとProxy Triangle Percentで調節できるそうです。
<Vertex Precision>
Position Precisionについてです。通常はAutoにセットされてNaniteが適切なPrecisionを選びます。
ここでAutoじゃなくて手動で値を設定しないといけない時はどういう時なのかが良く分かりませんね。
<Proxy Mesh>
うーん。理解した限りで書くと、NaniteでRendering出来ない箇所をProxy Meshと言う技法でRenderingしているみたいです。
そのProxy Meshの使用割合を
で決定しているみたいです。
Proxy Meshと通常のNaniteで作成されたStatic Meshの比較が載っていますがProxy Meshで代用している箇所のMeshの精度はあんまり良くないですね。
通常のNaniteのRendering
Proxy Meshを使用したRendering
自分でも試してみようとしたんですが、そもそもNaniteのStatic Meshを作成していませんでした。
後で実際にNaniteを作成する時に、この辺の事もテストします。
<Using Custom Proxy Mesh LODs for Nanite-enabled Meshes>
LODにProxy Meshを使用する方法について解説しています。
手動でProxy Meshの精度を指定していますが、手動の方が好ましい場合についての説明はほとんどないです。
7.8 Performance and Content Issues
Naniteは2つの技術、fine-grained level of detail とocclusion cullingを使用する事で画面上のMeshの数を常に一定かつPixelの数に対して比例した数に保つそうです。
そういう話から始まったらfine-grained level of detail とocclusion cullingについての説明が始まると思いますがそれについては特に何もなかったです。
あ。最後まで読んだら分かりました。
これからこれらのTechniqueが使用出来ない場合について解説するんでした。
<Aggregate Geometry>
Aggregate geometryは沢山の小さなバラバラの物が遠くで一つのVolumeに成る事だそうです。これはLevel of detailとCullingの両方の技術が対応出来ないそうです。
ここ読むとfine-grained level of detail とocclusion cullingってNaniteのために開発された新しいTechniqueと言うより、単なるLevel of detailとCullingの事を指しているように読めます。
それだと前の節でfine-grained level of detail とocclusion cullingについて解説していないのも納得なんですが、どうなんでしょう?
2段落目の文章で何で、NaniteがAggregate geometry(沢山の小さなバラバラの物が遠くで一つのVolumeに成る)に対して威力を発揮できないのかが説明されていました。
元々、Naniteは小さなMeshの三角が遠くに有る時は大きなMeshの三角に置き換えて表現します。Aggregate geometry(沢山の小さなバラバラの物が遠くで一つのVolumeに成る)が遠くに有るときは、大きな三角一個にならずに雲みたいになります。のでNaniteの威力が発揮できないそうです。
更に3段落目の文章で、Occlusion Cullingが何でAggregate geometryを破壊するのかについて解説していました。
Occlusion Cullingは非常に細かいけど、その粒度(Granularity) はPer Pixelではないそうです。
うーん。もうOcclusion Cullingが何であるかについては常識になっていますね。
一寸先に、Occlusion Cullingについて調べます。
Cullingと同じ意味でした。
はい。それなら説明する必要ないですね。
もう一つ、この文章でfine-grainedを非常に細かいけど、Pixelサイズよりは少しだけ大きいと言う意味で使用していました。fine-grained level of detailの方もPixelサイズよりは少しだけ大きいLODと言う意味で使用しているのかもしれません。
文章の続きを読んでいきます。
Occlusion Cullingは非常に細かいけど、その粒度(Granularity) はPer Pixelではないそうです。の続きからです。それでOcclusion Cullingを行うと(Aggregate geometryに対しては)Pixel毎には奥の物体が見えたりしている箇所が沢山あってその場合、奥の物体の三角形のMeshも描いてしまいその結果Renderingが遅くなるそうです。
納得です。
fine-grained level of detail とocclusion cullingが何を指しているのか分からないと、雲を掴むような話をしている感じになりますが、その二つが理解出来れば、理解出来ます。
ただlevel of detailについては私あんまり知らないんですが、UE5じゃなくてUE4の場合は、使用するTextureのサイズが変わるだけじゃなくてMeshのサイズも変わるんでしたっけ。その辺の記憶が曖昧です。
最後の文が木について語っているみたいなので一応、読んでおきます。
Occlusion Cullingの問題に当てはまる最適な例が、FoliageタイプのMeshだそうです。最初LandscapeのFoliageの事を言っているのかと思いましたが、単に葉が一枚一枚作成されている木全般を指しているみたいですね(勿論、Landscapeの場合も含みます)。
結論から言えば、確かにNaniteの効果は予測していた程は発揮できないけど、Naniteを使用しないよりは使用した方が効果は高いと言っていますね。
はい。
ここは以上ですね。
<Closely Stacked Surfaces>
沢山のStatic Meshが詰まった表面と言う意味でしょうか?理由が分からなくても、Naniteが効かなそうな場所ではあります。
それでは文章を読んでいきます。
kitbashing workflowsの意味が分かりませんので調べたら、どうもバラバラのPartsを集めて一個のModelを作成する手法を言うみたいです。因みにKitbashingそのものの意味は色々なプラモデルのパーツを使ってオリジナルな作品を完成させる手法の事を言うそうです。
うーん。勉強になる。
でもこの文章読むと、こういう箇所が今までのCullingは使用出来ないけどNaniteのCullingならば出来るみたく書かれています。
あれ?
ここでは、Naniteがあんまり得意ではない部分についての解説じゃなかったの?
まあ、文章、全部読んでみてそれから判断します。
分かりました。今までのやり方よりはNaniteの方が全然ましなんですが、それでもこういう場合だとNaniteの凄さが発揮されにくいです。その理由は…。みたいな話でした。
はい。
後、Naniteを可視化してこの問題が起きている箇所はこんなImageになりますみたいな解説がありました。(以下にそのImageの一部を示します。)
うーん。良く分かりません。
ぼんやり写っている箇所がそうなんでしょうか?
<Faceted and Hard-edge Normals>
Facetedとは宝石のダイヤモンドのような沢山の面がある物質を指します。鋭角に面が接合されたらHard-Edge Normalは自然に誕生すると思うんですが、それって宝石のダイヤモンドみたいなやつですよね。
Naniteは宝石のRenderingにも比較的に弱いんでしょうか?
それでは文章を読んでいきます。
あれ。
まずFaceted normalと言う言葉がありました。私はこの節の題をFacetとHard-edge Normalと読んでいたんですが、これ見るとFaceted normalとHard-edge Normalと言う意味みたいですね。
うん。
Faceted normalって何?
そりゃ、多面体には沢山のNormalが有りますが、それを敢えてFaceted normalとは呼ばないと思います。何か特別な意味がないと。
調べます。
Googleで検索したら一発で出て来ました。
ただ元のサイトがどんなサイトなのか良く分からないです。
勿論、こういうきちんとした情報が書かれているサイトだからしっかりした人が運営している可能性は高いんですが、もしかするとどっかにある情報を転載していて、何かアクセスする事で変な事されるようなサイトの可能性も少し感じました。ので今回はGoogle画面のみの引用に留めておく事にしました。
兎に角、Faceted normalが何かは分かりました。隣同士のMeshのNormalがPerpendicularなやつです。
つまりダイヤモンドのような多面体じゃなくて、立方体を指していたんです。
はい。勉強になります。
まずFaceted normalはVertex Shadingのコストを高くするので注意しろと言っています。
その後にMeshの頂点の数は三角形の数より少なくしろと言っています。
???
私はこの三角形ってずっとMeshの三角形の事を指していると思っていたんですが、違うの?
あ。でも頂点が何個もの三角形の頂点を兼任している場合もあるわけか。
文章、全部読んだら意味分かりました。
Faceted normalを持つMeshは同じ三角形に成れないのでコストが凄いかかるらしいです。
だから必要な場合は仕方ないですが、必要じゃないのに作成した3D ModelにたまたまFaceted normalを持つMeshが入る事は絶対に避けるべきと書かれていました。
はい。
後、ここで言う三角はMeshの三角とは違うみたいですね。
最後にFaceted normalを持つStatic MeshがNaniteを使用しても全然コストが安くなってない事を示すイメージが載っていました。
この部分がFaceted normalを持つStatic Meshです。
Naniteによる三角の生成部分です。
非常に細かい三角が作成されています。コストが高いのが分かります。
こっちの扉はFaceted normalを持たないStatic Meshで作成されていてNaniteによってRenderingのコストが低くなります。
Naniteによって作成される三角形が大きいです。
はい。
分かりました。
<Performance of Typical Content>
ここでは具体的な数字を出してNaniteを使用する事でRenderingがこれだけ速く出来ます。と示しています。
そんだけです。
多分ですが、Naniteの技術そのものに対して懐疑的な人にとってはこれらの測定条件、並びに測定結果を見てあーでもないこーでもないと言うんだと思うんですが、私Naniteそのものが従来のRenderingより劣るとは全く思って無いので、こんな具体的な数字で示されても、はい。位しか言えないです。
以上です。
8.まとめと考察
今週は最後の方は集中力が切れてしまいました。
9.参照(Reference)
[1] CGHOW. (2021, December 4). Flower Effect in UE4 Niagara Tutorial | Download Files [Video]. YouTube. https://www.youtube.com/watch?v=37g1J8mImjg
[2] Epic Games. (n.d.-a). Math Hall Content Examples. Unreal Engine Documentation. Retrieved December 26, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MathHall/
[3] Epic Games. (n.d.-c). Utility Expressions. Unreal Engine Documentation. Retrieved December 26, 2021, from https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Materials/ExpressionReference/Utility/#distance
[4] Epic Games. (n.d.-b). Niagara Renderers. Unreal Engine Documentation. Retrieved December 26, 2021, from https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Niagara/EmitterReference/RenderModules/
[5] Cloward, B. [Ben Cloward]. (2021, November 18). Advanced Channel Packing - Shader Graph Basics - Episode 23 [Video]. YouTube. https://www.youtube.com/watch?v=m5bP-xc6Sgs&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=23
*1:Distance(Input UV with TexCoord[0] and Input Center Position