UE4の勉強記録

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

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する  マップの作製 Part 5

f:id:kazuhironagai77:20210411224752p:plain

<前文>

<Matt Gaetz氏とアジア人への迫害について>

米国下院議員であるMatt Gaetz氏の児童買春疑惑は大変なスキャンダルですが、Foxニュースを代表とする宗教右派の人達から、彼に対する批判は全く聞かれません。宗教右派の人達は、アニメの絵にすらケチつける位、児童買春に対して厳罰を求めていたのですから、今回のスキャンダルには責任もって対処して貰いたいです。

しかし、残念な事ですが、宗教右派の人達は、自分たちの仲間が行ったと思われる児童買春疑惑を追及する代わりに、アジア人を迫害する事に熱心な様です。今、アメリカ国内におけるアジア人への暴行件数はウナギ登りです。

勿論、このアジア人への迫害には、韓国系と黒人が仲が悪い傾向があるとか、中華街からコロナが流行ったなどの根拠の無い噂などの理由もありますが、根本は宗教右派がFOX NEWSを使って流行らせた手法「事実じゃない事を、さも事実であるかのようにうそぶいて、だから差別や暴行しても良いとの論調に持っていく。」が主な原因です。

私は昔から主張していましたが、Foxニュースを代表とする宗教右派の連中が嘘を言っているのは全てのアメリカ人が知っていたのです。知っていたのですが、それによる被害者が自分達でないから娯楽として受け入れていたのです。それが今回、コロナや連邦議会での暴動によって初めて自分達に害が及ぶ可能性が出て来たので、宗教右派を切り捨てる事に決定したのです。

大体、キリスト教自体が、罪を犯してしまった自分を悔いてその罪を背負って生きる。と言う人間の内面の問題を扱った宗教なので、人間の外面を扱う政治問題に介入する時点で、その組織がカルト化している証拠でしょう。潰されても仕方ないと思います。

罪を犯してしまったと言えば、嘘をついている事は結構、罪深く感じます。しかし彼等にはそれが無かったのは何故なんでしょうか?

多分ですが彼らが通う教会で「嘘をつく事をキリストが望んでいる。」と洗脳していたんでしょうね。それで嘘をつく事に対して無感性になってしまったんでしょうね。

そう言えば、今、日本でもネトウヨとかjアノンとか呼ばれている一団がいます。彼らは、PCR検査は無駄と主張したり、特定の政治団体の人(例えば、先週出て来たSidney Powell氏)を嘘をつきまくって擁護したりし、又その逆に非難していますが、彼らもまたカルト化した宗教団体の信者なんでしょうか?

そんな気がします。

Matt Gaetz氏の児童買春疑惑について興味を持ったせいで、最近、Redditばっかし読んでいたんですが、何で全てのアメリカ人が、Foxニュースを代表とする宗教右派の連中が嘘を言っているの知っていたのか分かりました。彼らが嘘をついているのは何となく、彼らの顔や彼らの話を聞いている人の表情から推測出来たのですが、一つ一つの具体的な問題に対してどこまでが本当で、どこから嘘なのかまでは私には分かりませんでした。アメリカ人が一つ一つの嘘を見抜けたのはRedditで全部のニュースのトピックについて徹底的に議論しつくしていたからだったんです。

Matt Gaetz氏の児童買春疑惑についてもあらゆる角度から議論されていて大変勉強になりました。こんだけ一つのニュースに対して、みんなで議論したら嘘ならたちまちばれる訳です。

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

<本文>

1.今週の予定

今週もLandscapeの勉強と作成を行います。以下の事を行います。

  • Displacement mappingの実装
  • 針葉樹用の緑と沼用の地面のMaterialの追加
  • 沼の整理
  • ゲーム内のlandscapeの作成。

今週でLandscapeの作成は終わらせられるように頑張ります。

2.Displacement mappingの実装

Displacement mapping を実装します。

2.1 Displacement mappingの勉強

取りあえず、Plane上でDisplacement mapping をやってやり方を完全に理解します。

Tutorialを探したのですが、これと言うヤツは見つかりませんでした。その中でこのTutorial(Easily Set Up Displacement Maps in Unreal Engine using Quixel Bridge)[1]が一番簡潔に、MegascansのDisplacement mappingの使用方法を説明していました。しかし途中でPolygonを増やしたplaneを作成するためにCinema 4Dを使用しています。この部分はBlenderで置き換える必要があります。

その後でlandscapeのDisplacementを作成します。取りあえず見つけたTutorialがこれ(How to Use Megascan Displacement for Landscapes in Unreal Engine 4)[2]です。

Blender からUE4にMeshをexportするのはどうしましょう?私はBlender2.8以降の新しいバージョンのやり方は知りません。このTutorial([New] Blender To Unreal Plugin!)[3]がBlenderからUE4へMeshをExportするやり方を説明していました。ざっと見た感じでは詳しく解説していそうです。

今のBlenderのバージョンを調べたら2.92が最新みたいです。昔2.80をdownloadした後、全く勉強していません。

Meshをsubdivideする方法さえ分かればそんな勉強する必要はないと思いますが、どうしましょう?この機会にBlenderの使用方法も勉強しましょうか?勉強するなら、2.92を入れた方が良いんでしょうか?

Tutorial([New] Blender To Unreal Plugin!)[3] ではBlender 2.83 を使用していました。ここで使用しているAdd-onであるBlenderToolが2.80に対応していれば、特に何もしなくても良いかもしれません。まあ最新のBlenderをここでDownloadしても別に良いですけど。

2.2 Easily Set Up Displacement Maps in Unreal Engine using Quixel Bridge[1]の勉強

先にこのTutorialを途中までやってから考えます。

使用しているTextureですが、MegascansからではなくGameTexture.comからBridgeにImportしてそれを更にUE4にexportしていました。

f:id:kazuhironagai77:20210411224910p:plain

そのやり方は前のTutorialを見てね。って。

あー。

凄い分かり易いと思ったのに。

しょうがないですので、前のTutorialである、Converting Your Favorite Render Engine Materials for Unreal Engine[4]を見たら、最初の5分で滅茶苦茶分かり易く説明されていました。例に使用されていたのはRd-Textures社からのdownload方法ですが、多分同じでしょう。

これなら出来そうです。

f:id:kazuhironagai77:20210411224932p:plain

あれ、無料じゃないの。

f:id:kazuhironagai77:20210411224946p:plain

フェエエー。

この人がTutorialを作成した時はFreeになっている。

f:id:kazuhironagai77:20210411225003p:plain

今はPremiumです。

ちょっと考えます。

他の会社のTextureをQuixel BridgeにImportしてそれをUE4にExportする方法は試してみたいです。

これがFreeなのでこっちで試してみます。

f:id:kazuhironagai77:20210411225019p:plain

Downloadしました。

f:id:kazuhironagai77:20210411225033p:plain

Quixel Bridgeを開きます。

f:id:kazuhironagai77:20210411225046p:plain

Converting Your Favorite Render Engine Materials for Unreal Engine[4]ではZipの状態でImportするよりは、開いてImportした方が良いと言っていますが、

面倒なのでImport Zip Filesでやってしまいます。

f:id:kazuhironagai77:20210411225100p:plain

f:id:kazuhironagai77:20210411225108p:plain

となっています。

f:id:kazuhironagai77:20210411225124p:plain

四角で囲ったMrao.pngだけImportしませんね。これは何なんでしょうか?

Metalness-Roughness-Ambient Occlusionの略だそうです。となるとこれもImportする必要がありますね。

以下の様に変更しました。

f:id:kazuhironagai77:20210411225139p:plain

Importします。

2kでUE4にexportします。

f:id:kazuhironagai77:20210411225155p:plain

普通に出来ました。

と思ったら、Tutorial([New] Blender To Unreal Plugin!) [3] でEnable Displacementにチェックを入れてからImportしろと言っています。

f:id:kazuhironagai77:20210411225214p:plain

更に、Quixel BridgeでもDisplacementにチェックが入っているかを確認しろとあります。

f:id:kazuhironagai77:20210411225232p:plain

もう一回Importし直しました。

Material instanceを開くと以下の様になっています。

f:id:kazuhironagai77:20210411225254p:plain

サンプルの様な銀ピカではないですね。

それはともかく、

以下のDisplacement Amountの値を変化させればDisplacementが起きるそうです。

f:id:kazuhironagai77:20210411225311p:plain

だいたい8くらいから以下の様に飛び出してきました。

f:id:kazuhironagai77:20210411225327p:plain

以上でした。

これはこれで知らなければならない事なのですが、Displacement mappingの実装 (implementation) についての解説、つまりBPの書き方についての解説が全くなかったです。

このTutorialでも述べられていましたが、MegascansからTexture をUE4にExportする時にMegascansがDisplacement mappingを実装したMaterial とそのInstanceを作成してくれるので、BPを敢えて触る必要はないからです。

これは、そのMaterial Instanceのパラメーターを調節して最適値を見つける事が仕事であるdesignerにとっては適切な勉強範囲ですが、ゲーム制作でEngineerになるためにUE4を勉強しているProgrammerにとっては正しくないです。UE4を使用したゲーム制作でEngineer を名乗るためには、UE4におけるDisplacement mappingの実装方法を知る必要があります。

ちょっと考えます。

後、おまけですがMaterialの実装を変更してもっと銀色にしてみました。

元のMaterialの実装を見てみたらMetalnessのoutputにRPGを使用していました。

f:id:kazuhironagai77:20210411225347p:plain

新しいMaterialを作成してMetalnessにR、RoughnessにGを接続しました。

f:id:kazuhironagai77:20210411225403p:plain

銀色に光りました。

f:id:kazuhironagai77:20210411225426p:plain

2.2 Displacement mappingのBP内における実装について

考えた結果、判明したんですが、確かにUE4におけるDisplacement mappingのBPの実装  (implementation) そのものについては勉強出来ませんでしたが、それ以外でUE4でDisplacement mappingを使用するために必要な事は全て勉強出来ました。

もう一つ大事な事を忘れていたのですが、先週、Displacement Mappingについて自分でまとめていました。

この内容を読み直してみたら、displacement mappingの実装 (implementation) 方法について書いていました。

これを復習します。その後で、Megascansが提供しているMaterial内でどのようにDisplacement mappingが実装されているのかを確認してみます。これで多分、UE4におけるdisplacement mappingの実装方法について勉強出来ると思います。

2.2.1 先週のBlogにおけるDisplacement mappingのまとめ

先週のblogにおけるDisplacement mappingは簡単でした。

MaterialのOutputは以下の様になっています。

f:id:kazuhironagai77:20210411225502p:plain

この中でDisplacement Mappingに必要なのは、World Displacement とTessellation Multiplierです。

この二つを使用するためには、以下の事をする必要があります。

f:id:kazuhironagai77:20210411225521p:plain

World Displacementはverticesの位置を移動させます。Tessellation MultiplierはLandscapeの表面のポリゴンの量をどれくらいにするかを指定します。

のでWorld Displacementの値を変化させます。

f:id:kazuhironagai77:20210411225608p:plain

Displacement Mappingが出来ました。

2.2.2 World Displacement とTessellation Multiplierについて

ちょっと古いですが公式のDocumentでWorld Displacement [5]とTessellation Multiplier [6]が解説されていました。

World Displacementについてですが、

f:id:kazuhironagai77:20210411225636p:plain

と書かれています。

Tessellationってポリゴン化する事でしょう?Tessellation Verticesってどういう意味なんでしょうか?ポリゴン化した後のVerticesを動かすと言う事なんでしょうか?

このサイト (What is Tessellation in computer graphics )[7] によると

f:id:kazuhironagai77:20210411225701p:plain

Tessellationとはポリゴン化するだけではなく、ポリゴンを更に細かく分割する行為も含まれるようです。

この意味から推測するとTessellation Verticesは、ポリゴンを更に細かく分割した際に生成された頂点を指すと思われます。

最初はポリゴン化した後のVerticesをTessellation Verticesというのではないかと予測しましたが、どっちが正しいのでしょうか?

What is Tessellation in computer graphics [7] のDragonseel氏の解答にほとんど答えが書かれていました。

彼の解答によるとTessellationはTessellation Control Shader, Tessellation Primitive Generation, そして Tessellation Evaluation Shaderの3つのShaderで行われるそうです。

そんなShaderは知りません。初めて聞きました。

それぞれのStageでは、

  • Tessellation Control Shaderでは、頂点を更に細かくするために、細分化のタイプと新しく作成する頂点の数を指定します。
  • Tessellation Primitive Generationでは、Tessellation Control Shaderで指定した条件で実際に細分化します。この過程はHardwareが勝手にやる為Programmerは関与出来ません。
  • Tessellation Evaluation Shaderでは、細分化した際に発生した新しい頂点を呼び出して色々な事をしますが、どのようにポリゴン化するのか、とその呼び出した頂点の位置を指定したりもします。

が行われるみたいです。

はい。

分かりました。

順番が逆になってしまいますが、Tessellation MultiplierがTessellation Control Shaderにおけるポリゴンの細分化の条件を指定して、World DisplacementがTessellation Evaluation Shaderにおける細分化した際に発生した新しい頂点の位置の指定を担当していると考えると辻褄があいます。

となるとTessellation VerticesはTessellation Evaluation Shader内で呼び出されるTessellation Primitive Generationで新しく作成された頂点を指しているはずです。

もう一度、公式のDocumentのWorld Displacement [5]を読み直してみると

f:id:kazuhironagai77:20210411225742p:plain

Meshのベースの頂点ではなくて…とわざわざ述べています。

やっぱりこの文章からもTessellation VerticesはTessellation Evaluation Shader内で呼び出されるTessellation Primitive Generationで新しく作成された頂点を指していると考えられます。

はい。

ところでTessellation MultiplierがTessellation Control Shaderにおけるポリゴンの細分化の条件を指定できるならBlenderで予め細かくしたplaneを作成してUE4にimportする必要もないんじゃないでしょうか?

ムム…。

検討してみましょう。

ですがその前にMegascansが提供しているMaterial内でどのようにDisplacement mappingが行われているのかを確認します。

2.2.3 Megascansが提供しているMaterialのDisplacement mappingについて

以下の様な実装になっていました。

f:id:kazuhironagai77:20210411225809p:plain

MF_DisplacementノードのHeight(s)がどうなっているのか次第ですね。

以下の様になっていました。

f:id:kazuhironagai77:20210411225830p:plain

私が先週適当に作成したのか以下のヤツです。

f:id:kazuhironagai77:20210411225850p:plain

最初の掛け算の部分は、50のConstantを賭けているのがDisplacement Amountに変更されただけでほぼ同じです。Megascansの方はその後で、Displacement Amountを2で割った値を引いています。更にVertexNormalWSをかけています。

そう言えば、公式のDocumentのWorld Displacement [5]でもVertexNormalWSを掛けていました。

f:id:kazuhironagai77:20210411225913p:plain

VertexNormalWSって何の値なんでしょうか?

VertexNormalWSの公式のDocument [8] を見てみました。

f:id:kazuhironagai77:20210411225938p:plain

World座標における頂点の法線のデータみたいです。

しかし超大事な事をその後で言っています。この値はvertex shader内で実行される場合のみ使用出来ますと。

となると、以下の部分の計算はVertex Shader内で行っているはずです。

f:id:kazuhironagai77:20210411225958p:plain

ここで頂点の法線で掛けている訳ですからこの時点で頂点以外のDisplacement mappingの値は消えてします訳です。

つまり、先程考えていたTessellation VerticesにDisplacement mappingの値を直接パスする事は出来ないと言う事になります。

勿論、UE4のMaterialの使用方法を極めれば出来るのかもしれませんが上記のような組み方では無理でしょう。

ただしTessellation Verticesの分割具合とDisplacement mappingの変化を見ると、

以下の様にTessellation VerticesがBaseのVerticesと同じ時は、

f:id:kazuhironagai77:20210411230020p:plain

全くDisplacementが起きていませんが、

f:id:kazuhironagai77:20210411230039p:plain

以下の様にTessellation VerticesがBaseのVerticesより沢山生成された場合は、

f:id:kazuhironagai77:20210411230058p:plain

Displacementが起きています。

f:id:kazuhironagai77:20210411230123p:plain

BaseのVerticesの法線のみがDisplacementのデータを持っていてこんな結果になるんでしょうか?

実際はTessellation Verticesの法線とDisplacementのデータを掛けているんじゃないんでしょうか?と思いました。

直接、Shader code見れば何か分かるかもと試してみましたが以下の量のShaderが表示されました。

f:id:kazuhironagai77:20210411230141p:plain

流石に、今の私ではこれを読んで理解するのは無理です。

これはあきらめます。

最後にですが、私が先週作成したDisplacement mappingの実装にVertexNormalWSを掛けた所、

以下の結果が、

f:id:kazuhironagai77:20210411230157p:plain

こんな風になりました。

f:id:kazuhironagai77:20210411230211p:plain

Displacementの高さ以外の軸に対する値が0になったみたいです。

2.3 Tessellation Multiplierの使用方法について

厳密に言えばTessellation Multiplierを使用する目的は、Meshの分割をカメラからの距離に応じて指定するもので、Displacement Mappingとは違います。しかしLandscapeにDisplacement Mappingを使用する時は、必ずTessellation Multiplierも指定する必要があるので一緒にここで勉強します。

公式のDocumentのTessellation Multiplier [6]で解説されていますが、今まで勉強した以上の情報は書かれていません。

以下にMegascansから提供されたMaterialの実装部分を示します。

f:id:kazuhironagai77:20210411230234p:plain

3つのparameterがあります。Distance Offset, Distance Fade, そしてTessellation Multiplierです。

まずこれらのParameterの意味を調べます。

以下の様なセットを作成しました。

f:id:kazuhironagai77:20210411230251p:plain

これでParameterをいじって配置してある銀色の球のmeshの変化を見ようと思います。

まずは何もしていない状態です。

f:id:kazuhironagai77:20210411230307p:plain

Distance Offsetを1000まで上げました。

f:id:kazuhironagai77:20210411230321p:plain

最初の球のmeshが細かくなりました。

数字を挙げると奥の球のMeshも更に細かくなりました。

Offsetと言う名前から考えても、この数字が高くなるとMeshが細かくなり始める位置がカメラにもっと近づくのではないでしょうか?多分ですが。

次はDistance Fadeの値を変化します。

500から5000に変えました。

f:id:kazuhironagai77:20210411230336p:plain

これも最初の球のMeshが更に細かくなりました。Distance Offsetの時と違い、次の球のmeshも少しだけ細かくなっています。

距離によってMeshの細かさが減少しますが、その減少の割合を操作するParameterみたいです。数値が大きい程減少する割合が小さくなるみたいです。

最後はTessellation Multiplierです。これは見なくてもMeshの細かさを調節するParameterと予想出来ます。

初期値からTessellation Multiplierの値を変えたら、何も変化しませんでした。

良く考えたら、Tessellation Vertices がbase のmeshと同じなら分割の数をいくら増やしても0*(分割の数)なので変化ないのは当たり前でした。

以下の条件でやってみます。

f:id:kazuhironagai77:20210411230353p:plain

Tessellation Multiplierの値を2にしました。

f:id:kazuhironagai77:20210411230410p:plain

明らかに頂点の分割が細かくなっています。

此処まで理解したのでもう一回以下の式を参考にして考えてみます。

f:id:kazuhironagai77:20210411230425p:plain

Distance Offsetの値を凄く高くすると、Subtractで値がマイナスになりDivideでDistance Fadeがどんな値でもマイナス。よってSaturateで0に補正され1-xでは1となるはず。

ので、Distance Offsetの値がある程度以上の大きくなると全ての球のメッシュの分割が同じ様に起きると考えられます。

実際は、

f:id:kazuhironagai77:20210411230444p:plain

Distance Offsetの値を幾ら大きくしても近いmeshの方が細かく分割されています。

うーん。分からない。

How to Use Megascan Displacement for Landscapes in Unreal Engine 4 [2]を見たら、完璧に説明されてました。

2.4 How to Use Megascan Displacement for Landscapes in Unreal Engine 4 [2]で学ぶTessellation Multiplierの使用方法について

このTutorialで説明されていた通りに説明します。

まずDistance fadeですが、カメラのある位置からどれくらいの距離まで、Meshを細分化するかを決定します。

以下の例ではDistance fadeの値が5000です。

f:id:kazuhironagai77:20210411230507p:plain

Distance fadeの値を10000に増やしました。カメラから更に遠くのMeshまで細分化されています。

f:id:kazuhironagai77:20210411230522p:plain

Distance Offsetはこの細分化の距離を更に遠くに伸ばします。

f:id:kazuhironagai77:20210411230539p:plain

正直、Distance fadeとの違いが分かりません。

最後にTessellation Multiplierですが細分化の割合を細かくします。

f:id:kazuhironagai77:20210411230554p:plain

これは前から分かっていました。

Distance OffsetとDistance fadeの違いが分かりました。

Distance Offsetを3000、Distance fadeを0にした場合です。

f:id:kazuhironagai77:20210411230611p:plain

Meshの細分化のされ具合が距離に全く影響されていません。

一方で、Distance Offsetを0、Distance fadeを5000とした場合、

f:id:kazuhironagai77:20210411230626p:plain

Meshの細分化のされ具合が距離よって変わっています。

Distance Offsetを1000、Distance fadeを5000とした場合、最初の1000の部分は全て均等に細分化され、その後、距離に応じて細分化が減少しています。

f:id:kazuhironagai77:20210411230650p:plain

はい。完璧に理解しました。

Distance Offsetについてですが、何で球のmeshで試した時は距離に応じてmeshの細分化が変化したのでしょうか?

f:id:kazuhironagai77:20210411230711p:plain

多分ですが、meshの細分化はLODなどの別の要素の影響もあると思います。

その結果、球のmeshのこの条件では上手く出なかったのでしょう。

2.5 How to Use Megascan Displacement for Landscapes in Unreal Engine 4 [2]で解説された重要な点について

<Displacement Amountの正しい値の見つけ方>

Bridgeからmaterialを選択して3Dを表示させます。

f:id:kazuhironagai77:20210411230738p:plain

そのイメージと同じ位のデコボコになるようにDisplacement Amountの値を調節します。

f:id:kazuhironagai77:20210411230752p:plain

<Landscapeに今回の方法でTessellationをする場合の注意>

LandscapeにかかるTessellationはMaterial Instanceからだけではなく、LandscapeのLODからも影響されます。

LODからの影響を無くしたい場合は、LODのMax LODLevelの値を0にセットします。

f:id:kazuhironagai77:20210411230814p:plain

更にTessellationのTessellation Component Screen Sizeを0.01、Use Default Falloffのチェックを外します。

f:id:kazuhironagai77:20210411230830p:plain

こんな感じです。

f:id:kazuhironagai77:20210411230846p:plain

Materialの設定を変えないとDisplacement mappingはLandscapeを一枚の大きなタイルとしてみなすそうです。

その設定は、MaterialのTessellationにあるCrack Free Displacementです。これのチェックを外します。

f:id:kazuhironagai77:20210411230902p:plain

結構重要な情報が説明されていました。

2.6 LandscapeにDisplacement mappingを実装します。

それでは実装します。

まずLandscapeに使用しているMaterial instanceの元のMaterialである、Landscape4のTessellationのD3D11Tessellation ModeをFlat Tessellationに変更します。

f:id:kazuhironagai77:20210411230931p:plain

Landscape4では3つのMaterial functionが使用されています。

f:id:kazuhironagai77:20210411230945p:plain

まず、一番使用面積の大きいMF_GroundにDisplacement mappingを追加します。

MF_Displacementを使用する事にしました。

f:id:kazuhironagai77:20210411230959p:plain

Displacement TextureをMF_DisplacementのHeight(s)につなげます。

f:id:kazuhironagai77:20210411231014p:plain

UVsにつなげるTexCoordのサイズが分かりません。取りあえず、

f:id:kazuhironagai77:20210411231030p:plain

と繋げました。

Tessellationが効いているのは確認出来ますが、

f:id:kazuhironagai77:20210411231047p:plain

値を弄っても全く変化しません。

f:id:kazuhironagai77:20210411231111p:plain

別なMapにMF_Groundのみを使用したMaterialを作成してLandscapeに適用して確認します。

f:id:kazuhironagai77:20210411231127p:plain

f:id:kazuhironagai77:20210411231138p:plain

普通に効いています。

Landscape4に直接、MF_Displacementを追加してみます。

f:id:kazuhironagai77:20210411231205p:plain

今度はLandscape4_Instの値から操作出来ました。

f:id:kazuhironagai77:20210411231222p:plain

良く分かりませんが、Landscape4の場合はMF_GroundだけにMF_Displacementが在る場合は効かないようです。

Play画面から確認しようとしたら、8000枚位のShaderをCompileし直す必要があると出て来て、5分位ずっと計算しています。

f:id:kazuhironagai77:20210411231241p:plain

足が浮いています。

f:id:kazuhironagai77:20210411231255p:plain

うーん。

Displacementを切っても浮いていました。

f:id:kazuhironagai77:20210411231311p:plain

Displacementは関係なかったです。

以下の条件でマイルドにしました。

f:id:kazuhironagai77:20210411231331p:plain

f:id:kazuhironagai77:20210411231339p:plain

f:id:kazuhironagai77:20210411231349p:plain

一応出来ました。

後は負担がどれくらいなのかをAssessmentしたいです。

2.7 Displacement mappingの実装についてのまとめ

一応、Displacement mappingの実装が出来ました。出来ましたが結構な問題や分からない事は山積みですので、後で見直す時に忘れない様に、ここにまとめて置く事にします。

  • MF_Ground用のDisplacement mappingLandscape全体に使用している。
  • Displacement mappingのコストが分からない。
  • Characterの足が浮いている。

Displacement mappingの理論でも以下の部分は良く分かりません。

  • World Displacement に繋ぐノードでVertexNormalWSを使用しているが、これらはVertex shaderで実行されるのかそれともTessellation Evaluation Shaderで行わるのか不明。
  • Materialから生成したShaderのコードが複雑すぎて読めない。

頂点を沢山持つPlaneをImportしてDisplacement mappingを試す必要なくなったので、[New] Blender To Unreal Plugin! [3]は勉強する必要は無くなりました。しかしBlenderの新しいVersionも勉強する必要があります。それも考えておきます。

3.針葉樹用の緑と沼用の地面のMaterialの追加

3.1 沼の作成

以下の部分が沼です。

f:id:kazuhironagai77:20210411231457p:plain

今は、地面がむき出しですが、沼用の新しいMaterial functionを追加してここにPaintしようと思っています。

f:id:kazuhironagai77:20210411231515p:plain

沼用のMaterialをMegascanからimportしました。

f:id:kazuhironagai77:20210411231534p:plain

上記のTextureを使用したMaterial Functionを作成します。

MF_Groundを複製してTextureだけ交換しました。

f:id:kazuhironagai77:20210411231551p:plain

Texture SamplerのSampler sourceの設定がShard:Wrapになっているかの確認も行いました。

f:id:kazuhironagai77:20210411231620p:plain

Landscapeに使用しているMaterial、Landscape4に先程作成したMF_Swampを追加しました。

f:id:kazuhironagai77:20210411231637p:plain

一回、何かをBPに追加するたびにShaderがcompileを始めて、4000~7000位のShaderがCompileするまで待たなくてはいけないのですが、これって普通なんでしょうか?

後、Landscapeが完成したらCompileにこんな時間はかからなくなるのでしょうか?

以下のようにPaintしました。

f:id:kazuhironagai77:20210411231657p:plain

Parameterを調整します。

f:id:kazuhironagai77:20210411231720p:plain

良いんじゃないでしょうか?

実際にPlayしてみました。

f:id:kazuhironagai77:20210411231737p:plain

良い感じです。

このLayerに枯れ木をFoliageとして追加します。

Foliage4のLandscapeGrassOutputにSample’Swamp’を接続します。

f:id:kazuhironagai77:20210411231759p:plain

更にLandscape Grass Type、Swamp_Foliageを作成して

f:id:kazuhironagai77:20210411231832p:plain

f:id:kazuhironagai77:20210411231844p:plain

LandscapeGrassOutputにセットします。

f:id:kazuhironagai77:20210411231904p:plain

以下の様になりました。

f:id:kazuhironagai77:20210411231924p:plain

枯れ木の数を減らして、サイズを大きくします。

最終的に更に2種類枯れ木を追加して以下の様になりました。

f:id:kazuhironagai77:20210411231947p:plain

Play中の画面です。

f:id:kazuhironagai77:20210411232011p:plain

大変重いです。

3.2 Componentの削除

一々Compileするたびに3000枚のShaderをCompileしていて大変、イライラします。

以下のlandscapeから要らないComponentを削除します。少しはCompileにかかる時間が短縮するでしょう。

f:id:kazuhironagai77:20210411232125p:plain

あんまり削れませんでしたが、一寸はマシになるでしょうか?

f:id:kazuhironagai77:20210411232157p:plain

テストして気が付いたんですが、Foliageで生成した木とは衝突しません。

f:id:kazuhironagai77:20210411232219p:plain

どう直せばいいんでしょうか?

このサイト[9]の解答を見ると無理みたいですね。

f:id:kazuhironagai77:20210411232239p:plain

なるほど。

もう十分勉強したのでCh4に戻って本番用のLandscapeを作成します。

4.ゲーム内のlandscapeの作成。

4.1 Height mapからLandscapeをImportする

久しぶりにCh4_3を開きました。

Map1を以下に示します。

f:id:kazuhironagai77:20210411232313p:plain

ここに前節で作成したLandscapeとほぼ同じ物を作成したいと思います。

まず、前に作成したLandscapeを消します。

f:id:kazuhironagai77:20210411232335p:plain

これは予想外でした。こんなにLandscape小っちゃかったんですね。

やっぱり別なMapにします。

となると先程作成したMapを丸ごとExportすればいいんじゃないでしょうか?

f:id:kazuhironagai77:20210411232408p:plain

出来ました。

こっちはこっちで別なLandscapeを作成しましょう。

f:id:kazuhironagai77:20210411232425p:plain

5.Map1Landscapeの作成

以下の様な地形を作成します。

f:id:kazuhironagai77:20210411232453p:plain

上の地形を元に以下の様なLandscapeを作成しました。

f:id:kazuhironagai77:20210411232512p:plain

Landscape4で使用したMaterialでPaintしました。

f:id:kazuhironagai77:20210411232532p:plain

Play中の画像です。

f:id:kazuhironagai77:20210411232551p:plain

6.Environmentの勉強

今週は思っていたよりも早く予定した内容が終わってしまったのでUE4 の勉強をする事にします。

2021-03-22のブログで以下のTutorialは光に関するものだから勉強しませんでした。

  • Becoming an Environment Artist in Unreal
  • Constructing Believable Environment

久しぶりにCH4_3を開いてPlayしたらcharacterの陰影の付き方が別のProjectと違うような気がします。ちょっと気になるのでUE4におけるLightingを先に勉強する事にします。

2021-03-22のブログを見ると、Landscapeの作成が終わったら以下の事をやると述べていました。

  • Widget内のBPの整理
  • Effectの勉強と作成

これは来週やります。

BlenderからUE4にExportするTutorialについては新しいBlenderの使用方法を別に勉強しないといけないので後に回します。

6.1 Becoming an Environment Artist in Unreal

< Introduction to Environment Art >

このコースで何が勉強出来るのかを説明しています。この説明を聞く限りあんまりLightingはやらないみたいです。後かなり初心者向けみたいです。まあ、軽い気持ちで映画でも見る気分で見て行きましょう。

<Department Interactions in Development

Environmental artistがゲーム制作に関して何を担当するのかを説明しています。

  • PropとAssetの作成。
  • Textureの作成。
  • Materialの作成。
  • Level Artistとの密接な連携
  • AssetのCollision、LODs、そしてLightmappingの作成。
  • Level制作に必要なパーツの作成

と説明されています。

これを見ると「Unreal Engine 4 で極めるゲーム開発」で述べられている職種は、少なくともUE4を使用したゲーム開発では一般的な概念のようです。

後、Lightingに関してはLight Mapの作成ぐらいしかここでは述べられていませんね。

<Names and Terminology

ここではゲーム制作で使用される専門用語の内、Environmental artistが知っておかなければならない用語とその意味が紹介されていました。

ここで、面白いのがこの用語の説明がArtist向けな所です。

例えば、C++のProgrammerがBuildについて説明するならば、Compile+linkingと言うでしょうが、ここではBuildとはVersion、特に最新のVersionを指していると説明されています。私も最初は、それはBuildで作成されたCode(のVersion)でBuildじゃないでしょう。と思ったんですが、ArtistにCompiler と Interpreterの違いかを説明したって彼らには必要ない事ですし、こっちの説明のほうが分かり易く、かつ実用的です。

これで思い出したのが、化学における有機、無機の違いと意識高い系の人のおける有機、無機の違いです。化学を勉強する人にとって有機、無機の違いは炭素原子を中心に構成されている分子かどうかですが、意識高い系の人にとっての有機、無機の違いは農薬を使用して栽培されているかどうかです。

<Setting Up Your Folders

作成したFileやFolderの整理の仕方についてです。

以下にFileの名前の付け方の例を紹介しています。

f:id:kazuhironagai77:20210411232703p:plain

今度はTextureの種類についての名前の付け方です。

f:id:kazuhironagai77:20210411232720p:plain

これは直ぐに実行しましょう。大変分かり易いです。

Quiz 1

Mipについて間違えてしまいました。

うーん。

Mipmapって色んなサイズのtextureを準備してそれぞれを距離に応じて使い分ける事でしょう。何で間違いだったんでしょうか?

Scale Prep for Unreal Usage

1 unreal unitが1 cmであると明言されていました。

更に単位の設定方法について説明されていました。

Project Setting -> Editor -> Appearance -> Distance/Length でCentimetersにセットされています。

f:id:kazuhironagai77:20210411232756p:plain

XYZ軸についてです。UE4ではz軸が上を向いています。(これについては昔、このブログで相当調べました。)

Pivotについてです。Pivotはmeshの中心点の事ですがmeshによって底の中心だったり底の右端だったりします。

Using the Grid and Snapping Tools

Gridとは何かについての解説です。

その中で以下のToolの使用方法について説明しています。

f:id:kazuhironagai77:20210411232829p:plain

いますが、

f:id:kazuhironagai77:20210411232848p:plain

この升目上のチェックを外すと設定が100になっていても自由に動かせる事についての説明がありませんでした。

これって結構重要だと思うんですがどうでしょう。

Mouseの真ん中のボタンを押しながらDragすると距離が測れるそうです。

やってみます。

f:id:kazuhironagai77:20210411232915p:plain

おお。出来ました。

これは中々良い事を学びました。

この距離を示す白線の始点と終点の位置も

f:id:kazuhironagai77:20210411232934p:plain

によって強制されていますね。自由に位置を選択したい場合は升目上のチェックを外すと出来ます。

Texture Settings, Density and Exporting

Textureについての解説です。

Base、Normal、 Metalness、 Roughness、Ambient occlusionそしてChannel Packedについての説明です。

いつも思うんですが、PBRを説明するのにこのBase、Normal、 Metalness、 Roughnessの4つのTextureが必要であるRendering方法とすると非常に分かり易くなります。

ここでの説明も非常にスッキリしていて短時間で本質が理解出来る仕組みになっています。

Textureのサイズについてですが、UE4は最大で8192x8192ですが、4096x4096以上を使用するのはかなりレアな場合だそうです。

2021-03-28のブログで、

f:id:kazuhironagai77:20210411233003p:plain

と述べていますが、この辺の確証が得られましたね。

Texture density についてですが、そのTextureのsizeではなくそのtextureのsizeとそのtextureが張られるmeshのサイズで決まるそうです。

以下の様にです。

f:id:kazuhironagai77:20210411233025p:plain

これってTextureをMeshに貼りつける時にかなり大切ですよね。あんまり細かいTextureを小さな面に貼っても誰も気が付かないですし。

Texture densityを可視化する機能とかあるんでしょか?

Importing Meshes and Textures Into Unreal

FBXをUE4にImportする時に、表示される以下のヤツの中で大切な項目の説明を行っています。

f:id:kazuhironagai77:20210411233052p:plain

BlenderからStatic meshをImportする時にいつも無視していました。

ここで勉強してしまいましょう。

f:id:kazuhironagai77:20210411233113p:plain

MeshをImportする時に一個だけとは限りません。この項目はどのMeshに対しての設定をするのかを示します。

f:id:kazuhironagai77:20210411233134p:plain

Skeletal Meshかどうかです。

f:id:kazuhironagai77:20210411233158p:plain

ここにCheckを入れておくと最低のCollision(多分以下に示したようなタイプ)は生成してくれるそうです。

f:id:kazuhironagai77:20210411233231p:plain

f:id:kazuhironagai77:20210411233239p:plain

Importする時に幾つかのAssetを同時にImportしていますが、それを一つのMeshとしてImportするそうです。

幾つかのAssetを同時にImportって例えばイスをImportする時に背もたれとか足を別々のAssetで作成しているんでしょうか?

それともイスとテーブルを同時にImportしてそれを一つのMeshにする事を指してるんでしょうか?

現状の私の3Dの知識では今一意味が分かりませんでした。

f:id:kazuhironagai77:20210411233303p:plain

ここの二つの項目、かなり力を入れて解説しているんですが、今一良く分かりません。

カーソルを上に乗せたら詳しい説明が表示されました。

Normal Import Methodは

f:id:kazuhironagai77:20210411233319p:plain

と書かれています。

つまりFBXは元々、頂点に対してか、その頂点が作成したポリゴンに対してかは分かりませんが、法線の値を保持しています。それをそのまま使用するか、もしくはImportした頂点のデータからUE4側で法線の値を計算し直すのかを聞いてるようです。

Normal mapに対して聞いている可能性もない訳ではありませんが、今の所それは不明です。

Normal Generation Methodは

f:id:kazuhironagai77:20210411233334p:plain

Meshの法線を計算するのにMikkTSpace tangent space generatorを使って計算せよ。と指定しています。

となるとFBXは元々保持している法線の値は頂点に対してと言う事になりそうですね。

MikkTSpaceなんてどっかで聞いた事がある言葉です。しらべればすぐに分かるでしょう。

このサイト(Tangent Space Normal Maps)[10]に詳しい解説がありました。

このサイトを読むとつまり、tangent space normal mapの作り方と戻し方を同じ方法でやらないと値が変わってしまう事やorder dependencyなどの問題があり、それらの問題をMikkTSpaceでやると避ける事が出来る。と言う事のようです。

そういう解釈でもう一回説明を聞いたら、そんなような事を説明していました。

f:id:kazuhironagai77:20210411233420p:plain

f:id:kazuhironagai77:20210411233428p:plain

これってXYZ軸の変換の事でしょうか?

f:id:kazuhironagai77:20210411233458p:plain

f:id:kazuhironagai77:20210411233509p:plain

こっちは単位の変換みたいですね。

f:id:kazuhironagai77:20210411233541p:plain

f:id:kazuhironagai77:20210411233549p:plain

ImportしたMeshにMaterialが無い時にどうするかを聞いています。

Tutorialの解説では、ほとんどのゲーム制作でUE4内で新しいMaterialを作成するそうです。

f:id:kazuhironagai77:20210411233605p:plain

f:id:kazuhironagai77:20210411233615p:plain

これは解説そのままですね。

これでFBX import optionの解説はお終いです。

正直、カーソルを分からない項目の上に合わせるのが一番分かり易いと分かりました。

次はImportしたTextureの設定についてです。

f:id:kazuhironagai77:20210411233633p:plain

圧縮の方法についての選択ですが、Base Colorとそれ以外ではそれぞれ最適なやり方が違います。

f:id:kazuhironagai77:20210411233656p:plain

これは流石に知っています。Base colorの時はチェックしてそれ以外は外すはずです。

f:id:kazuhironagai77:20210411233729p:plain

ここはImportしたFileがどこからImportしたのかの記録です。

f:id:kazuhironagai77:20210411233744p:plain

OpenGL用に作成されたNormal mapを使用する時にチェックします。これは2021-03-28のブログでも勉強しました。

結構勉強になりました。

Quiz 2

満点でした。でしたけどgrid snapping option valuesが何をいっているのか分からなくてこのブログを読み直して回答しました。

Blockouts and Stand-in Meshes

Blockoutとは仮のアセットでLevel上に取りあえず配置してLevel artistが全体のイメージが掴めるようにするためのものです。

Blockoutの例として紹介されていた地下鉄のドアですが、私には完成品に見える位の質でした。

ここは正直何を勉強すべきなのか良く分からないです。

Collison Setup

Collison用のmeshの作成方法についての解説でした。

Polycount, Optimization and Draw Calls

最適化についてです。

Polycountとは使用しているポリゴンの数です。少ないほど良いです。

Draw CallはRenderingのためにGPUやCPUからTextureを呼び出す回数を指しているようです。説明を聞きましたがこれ以上の理解は出来ませんでした。GPUに一端Textureやmeshのデータを渡してGPU内だけで呼び出すならそんなに負担にならないんじゃないの?と思ったんですがその辺をDraw Callが数えてるのか分かりません。

Draw Callの数を減らすためにはUE4のRenderingを理解したProgrammerが必要で、ArtistはDraw callを減らす事が最適化につながる事を理解する事と

  • Meshの数を減らす事
  • Materialの数を減らす事
  • 同じmaterialを使用しているMeshは結合できないか検討する事

だそうです。

LODについてです。

LODはアセットがカメラから遠くの時にmeshの数が少なる事だそうです。LODについてしっかり勉強した事ないので、どうやって実現しているのか全く分かりません。

MeshのLOD Settingから作成していました。

f:id:kazuhironagai77:20210411233835p:plain

更にReduction Settingでポリゴンに使用されてる三角形の数を減らす事も出来ます。

f:id:kazuhironagai77:20210411233851p:plain

カメラからの距離でどのLODを使用するかはUE4が自動で設定してくれるそうです。

以下のチェックを外すとその自動化が止まるそうです。

f:id:kazuhironagai77:20210411233907p:plain

自分で設定する時は以下のScreen Sizeで指定するそうです。

f:id:kazuhironagai77:20210411233919p:plain

Meshに使用されるMaterialの数が増えるほどDraw callも増えるそうです。LOD2などの遠くでのみ使用さるMeshのMaterialの数はLOD0より少なくする事も考えるべきだそうです。

かなりLODについて勉強になりました。

Quiz 3

満点でした。

Footprintって何ですかと一瞬なりましたが、解答読んだら理解出来ました。

Basic Material Creation and Application

Materialの作成方法についての実演でした。

大体知っている事でしたが、TextureSampleのSampler TypeにそのTextureがどのタイプが表示されているのかを示しているそうです。

f:id:kazuhironagai77:20210411233945p:plain

GameTexture.comからBridgeにImportしたMrao.pngですがLinear Colorにセットされていました。

f:id:kazuhironagai77:20210411234010p:plain

これってMASKをセットすべきですよね。

Material Masters and Instances

Material Instanceの作り方を実演しています。

Master Materialは一つのProjectで2,3個しか作らないと言っていますが本当なんでしょうか?

時間が無くなってしまいました。

今週はここまでとします。

7.まとめと感想

今週は、

  • Tessellation Multiplier を使用したDisplacement mappingの勉強と実装
  • Landscapeの沼の作成
  • 作成したLandscapeGame用のProjectMigrate
  • Game用のProject内で新しくLandscapeを作成
  • 時間が余ったのでEnvironment artist用のTutorialを勉強

を行いました。

来週は、

  • Environmental artist用のTutorialの続き
  • Widget内のBPの整理
  • Map1からLandscape4にWarp出来るようにする。
  • Landscape4で戦闘出来るようにする。

を行います。

8.参考文献(Reference

  1. (2021b, January 2). Easily Set Up Displacement Maps in Unreal Engine using Quixel Bridge [Video]. YouTube. https://www.youtube.com/watch?v=f7q7btWDYOc
  2. MR3D-Dev. (2020, November 23). How to Use Megascan Displacement for Landscapes in Unreal Engine 4 [Video]. YouTube. https://www.youtube.com/watch?v=uTKap2aJbI8
  3. Smart Poly. (2020, July 28). [New] Blender To Unreal Plugin! [Video]. YouTube. https://www.youtube.com/watch?v=PNGAoKhrBls
  4. (2021a, January 1). Converting Your Favorite Render Engine Materials for Unreal Engine [Video]. YouTube. https://www.youtube.com/watch?v=5vpDFGJEsNw
  5. Epic Games. (n.d.-a). 1.11 - World Displacement. Unreal Engine Documentation. Retrieved April 11, 2021, from https://docs.unrealengine.com/en-US/Resources/ContentExamples/MaterialNodes/1_11/index.html
  6. Epic Games. (n.d.-b). 1.12 - Tessellation Multiplier. Unreal Engine Documentation. Retrieved April 11, 2021, from https://docs.unrealengine.com/en-US/Resources/ContentExamples/MaterialNodes/1_12/index.html
  7. E., A., & D. (2016, February 9). What is Tessellation in computer graphics. Computer Graphics Stack Exchange. https://computergraphics.stackexchange.com/questions/2018/what-is-tessellation-in-computer-graphics
  8. Epic Games. (n.d.-c). Coordinates Expressions. Unreal Engine Documentation. Retrieved April 11, 2021, from https://docs.unrealengine.com/en-US/RenderingAndGraphics/Materials/ExpressionReference/Coordinates/index.html?utm_source=editor&utm_medium=docs&utm_campaign=rich_tooltips#vertexnormalws
  9. Epic Games. (2015, August 6). Landscape grass & collision. Unreal Engine Forums. https://forums.unrealengine.com/development-discussion/content-creation/50736-landscape-grass-collision
  10. MikkTSpace.com. (n.d.). Tangent Space Normal Maps. Retrieved April 11, 2021, from http://www.mikktspace.com/

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する  マップの作製など Part 4

f:id:kazuhironagai77:20210404222701p:plain

<前文>

Sidney Powell氏と匿名掲示

良くニュースとか洋物のドラマで聞く司法長官はthe United States Attorney generalでSidney Powell氏の前職であるUnited States Attorneyは連邦検事だそうです。

連邦検事がどれくらい凄いのか、法律にも権力にも疎い私は全く分かりませんが、良く洋物のドラマや日本のニュースに出て来る司法長官と一字しか違わないのだから、結構凄い地位だと思います。

そんな凄い職に就いていたSidney Powell氏ですが「2020の大統領選挙は投票の集計をする機械を作っている会社(Dominion社)が不正を働いているからトランプ氏が負けた。」とメディアで言いまくっていたら、とうとうDominion社から訴えられてしまいました。

そしたら彼女「私が言っているのは全て冗談で、それはみんな分かってる。もしそれが分からないヤツがいたら、そいつはとんでもないアホ。」と主張し始めました。

この発言は、右派、左派を問わずアメリカ人のほとんどが激怒、もしくは失笑する発言だったんですが、10年以上アメリカで暮らした私からすると、その激怒や失笑しているアメリカ人に対して「白々しい偽善者たち」と言う気持ちになります。

前にも書きましたが、宗教右派たちが主張する内容が全部嘘なのは全てのアメリカ人が知っています。知っていますが、メキシコの国境に壁を作った時や、日本を含むアジアにアメリカでは使用が禁止されている発癌性の農薬を使用したフルーツを販売した時は、アメリカ人全員が笑って見過ごしていたんです。ところが今回、コロナウィルスや議会の暴動で自分達に直接危害が及ぶ事が分かると、途端に宗教右派たちを叩き始めました。

しかし今回、ここで書きたいのはその話ではなく、この彼女の発言と日本の匿名掲示板についてです。

このニュースが日本の匿名掲示板で紹介された時「彼女はそんな発言していない。嘘を書くな。」と一貫して訂正してくる人達がいて、そのスレを読んでいるほとんどの人が本当はSidney Powell氏はそんな発言していないんだ。と信じてしまったんです。

私も信じてしまいました。

後で英語のニュースサイト見てたらSidney Powell氏が嘘をついていた事を認めたと書かれていて「えっ」となりました。

いくら匿名掲示板といえどもニュースを紹介しているサイトですから、そこに書かれている内容がある程度の事実を保証する義務があると思いますが、そう言う事は野放しみたいですね。

ここで皆さんに質問です。

  1. 皆さんは匿名掲示板といえどもニュースを扱う限りは、そこに書かれている内容に対してある程度の事実を保証する義務があると思いますか?
  2. もしその義務があるとすれば、それはそのサイトを運営する会社ですか?それともそこに文章を書き込む人達ですか?

私はこう考えています。

まず1に対してですが、ニュースと名乗っている以上、その内容に対してある程度の事実を保証する義務はあると思います。もしくは「ここで書かれている事はすべて嘘です。信じないで下さい。」と前もって書き込んでおく必要があると思います。そう言えば、昔はこの匿名掲示板、似たような警告が書かれていた気がします。

2に対しては、匿名で文章が書ける以上、その書かれた内容が事実である事を保証する義務はそのサイトを運営する会社にあると私は思います。

その辺のカルトに嵌っているおばちゃんが癌患者に「この水飲めば癌も治る。」と言ってもほとんどの人は信じないでしょう。しかしどっかの大学病院の先生が言ったら、ほとんどの人はひょっとしたら治るかもしれない位は思います。このように誰が発言したのかはその内容の信ぴょう性に対して大きく影響します。それを敢えて隠している訳ですから、その責任はサイトを運営する会社にあると私は考えます。

はい。

実はこの上記の議論と全く同じ議論がアメリカでも今行われています。

1については、先程のDominion社がFox Newsに対してもSidney Powell氏と同様の訴訟を起こしています。

その時にFox Newsは「我々は娯楽を提供しているのでそれが事実である事を保証する義務はない。」みたいな返答をしています。幾ら何でもNewsですからね。事実を伝える必要がないのならNews番組を名乗って良いんでしょか?と批判の嵐に晒されています。

2についてですが、アメリカ議会は今回の連邦議会での暴動の責任の一端がSNSの運営会社にあると激怒しています。

これに対してFace bookは全ての責任は発言した人、Face bookの責任は書いた記事がネットで読める様にする事である。と真っ向から対立しています。Googleは訳わからん事言って議員を煙に巻こうとして失笑を買ってしまいました。Twitter社はSNSの運営会社にも責任の一端があったと最初から認める発言をして株を挙げました。

この議論がどう転んでいくのか分かりません。しかし近い将来、匿名や偽名では、ネットに投稿出来なくなる気が私はしています。

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

<本文>

1.今週の予定

以下の事をやっていこうと思います。

  • Landscapeの直し
  • 先週勉強したTutorialの続きをやる
  • Foliageの改善(Cull Distanceの使用)
  • 水の追加
  • Projectに使用する実際のLandscapeの作成

後、今週からReferenceを別に作成しようと思います。

UE4を業務で使用している人で、英語の資料(YouTubeのTutorialも含む)が読めない人はいないと思いますが、膨大な英語圏の資料から質の高いものを見つけるのはかなり時間がかかります。「英語圏の資料は全く見ない。」のも一つの手かもしれませんが、UE4において英語圏の資料は質、量、共に日本語の資料を圧倒していますので、そんな習慣を付けてしまうと近い将来、必ず詰んでしまいます。

私のBlog内に引用した資料の一覧が有ると、それ自体がある程度の質を保証した英語圏の資料集なので一から探す手間が省けます。

また最近の私のブログの質はかなり向上して来ているので、私のブログで引用した資料と言う事で引用された側にもメリットがあるはずです。

ので引用した資料はReferenceを作成する事で明確にします。

2.Landscapeの直し

先週作成したMaterialには何か所か直したい所があります。

  • Material instanceを使用していないためパラメーターを調節するたびにCompileする必要がある。微調整が出来ない。
  • Displacement Textureが提供されているがこれの使い方が分からない。
  • 緑のTextureにもMacro variationDistance blendを使用する。
  • Distance BlendTextureのサイズの設定が逆だったかもしれない。

2.1 Material instanceを使用する。

先週勉強したTutorial [1]でパラメーターの微調整を実際のLandscapeを見ながらおこなっていました。

f:id:kazuhironagai77:20210404222902p:plain

これはかなりsmartなやり方です。早速真似しようとしたら出来なかったんです。

その理由ですが、先週Materialは作成したのですが、そのMaterial からMaterial instanceを作成しませんでした。

Materialを直接使用するとParameterを変える毎にCompileする必要があり、とても実際のLandscapeを見ながら微調整なんて出来なかったです。

Material Instanceを使用する理由はParameterの値だけが違う同じ方法で作成したMaterialらを一括で管理出来る事だと思っていたのですが、それプラス3d viewportから直接、そのmaterialを実際に使用しているActorを見ながらCompileなしでParameterの調整が出来る事でした。

目から鱗の体験でした。

先週作成したMaterialからMaterial instanceを作成します。

f:id:kazuhironagai77:20210404222919p:plain

しました。

これにParameterを追加していきます。

あれ。既に大量のParameterが存在しています。

f:id:kazuhironagai77:20210404222935p:plain

元のMaterialにParameter なんて一個もないんですが? 

f:id:kazuhironagai77:20210404222952p:plain

なんと、使用しているMaterial function内のParameterも自動で追加してくれてありました。

f:id:kazuhironagai77:20210404223006p:plain

となるとほとんど既に完成していました。

Distance blendに使用しているConstantをparameterに変換してテストしてみます。

f:id:kazuhironagai77:20210404223022p:plain

以下の様に設定を変更しました。

f:id:kazuhironagai77:20210404223039p:plain

Start Offsetを-1000から-2000に変更します。

f:id:kazuhironagai77:20210404223056p:plain

Blendが始まる箇所が遠くになっています。

Blend Range resultの値を100から100000に変更します。

f:id:kazuhironagai77:20210404223111p:plain

淡いブレンドに変化しました。

実際の状態で見てみます。

f:id:kazuhironagai77:20210404223126p:plain

うーん。

よーく見るとタイルが見えるんです。

Dirt far、 dirt nearの二つのParameterを追加する事で、使用しているTextureのサイズもMaterial instanceから調整出来る様にしました。

Farを0.02、nearを0.05で以下のような地面になりました。

f:id:kazuhironagai77:20210404223142p:plain

これならタイルタイルしていませんね。

実際のplay画面です。

木の葉のサイズが人の頭位になってしまってますね。

f:id:kazuhironagai77:20210404223157p:plain

うーん。

変えました。

f:id:kazuhironagai77:20210404223219p:plain

これぐらいでどうでしょうか?

f:id:kazuhironagai77:20210404223235p:plain

遠くに使用するTextureはサイズを変えるだけでなくTextureそのものも変えた方が良い気もします。

Material Instanceを作成する事で、compileなしかつ3d view portを見ながら微調整を行えるようにすると、体感的ですが1000倍位精度高く調整できる気がします。

今回はこの事が確認出来たので良しとしましょう。

2.2 Displacement Textureが提供されているがこれの使い方が分からない

Mega ScanからdownloadしたTextureにはすべてDisplacementと名付けられたTextureが付いています。

f:id:kazuhironagai77:20210404223259p:plain

f:id:kazuhironagai77:20210404223306p:plain

f:id:kazuhironagai77:20210404223315p:plain

これの使い方が分かりません。

調べます。

色々なサイトをつまみ読みしていたら概要が分かったのでまとめます。

まず3D graphics にはDisplacement Mappingという技術があります。

Normal mappingでは偽の法線を作成する事で疑似的な凹凸を表現しますが、Displacement Mappingでは頂点をDisplacement mapに沿って実際に移動させる事で本当の凹凸を作成します。実際に凹凸を作成するのでnormal mappingに比べて段違いでリアルな表面を作成出来ますが、これを可能にするためには沢山の頂点が必要になので、かなり高コストなmappingです。

UE4における使用方法ですが、それなりに説明しているサイトは何個かあるのですが、バッシと理論と実践を簡潔に説明している所は無かったので自分で理解した範囲でまとめておきます。

まずMaterialのTessellationのD3D11Tessellation ModeをFlat TessellationかPN Trianglesにセットします。

f:id:kazuhironagai77:20210404223333p:plain

するとWorld DisplacementとTessellation Multiplierが入力出来る様になります。

f:id:kazuhironagai77:20210404223350p:plain

Tessellation Multiplierは頂点の数をどれくらい増やすかを決めるための入力のようです。参考にしたサイトの多くは、カメラの傍は細かく頂点を増やして、ある程度から遠くは元のままの頂点にしたりしていました。

World Displacementはどれくらい頂点をずらすかを指定するための入力のようです。高さのみ変化するのかxyz方向全てに変化するのかは不明です。

試しに以下の様にdisplacement mapをWorld Displacementに繋げてみると、

f:id:kazuhironagai77:20210404223406p:plain

以下の様に球の形状が変化しました。

f:id:kazuhironagai77:20210404223421p:plain

今回は、

  • Displacement mappingが何であるか
  • UE4Displacement mappingを使用するために最低限必要な手順

が判明したので、ここで一端中止します。

この後、

  • この技術がどのくらい必要か
  • 使用するためのコスト
  • この技術を正しく理解し正しく使用する為に必要な勉強時間

などを考えてみて継続するか決めようと思います。

2.3 緑のTextureにもMacro variationやDistance blendを使用する

先週、Macro variationやDistance blendはDirtにしか追加しなかったのでこちらにも追加します。

緑のTextureはM_Ground_GrassをそのままMaterial functionに変更したものでMaterialの実装がDirtとは全く違っていました。

以下の三か所を見ると、先週やったMacro variationとはやり方が少し違うものの、既にMacro variationを実装していると考えられます。

f:id:kazuhironagai77:20210404223509p:plain

f:id:kazuhironagai77:20210404223516p:plain

f:id:kazuhironagai77:20210404223525p:plain

更に、距離を変化させてもタイルタイルしてる箇所は見られないばかりか、スムーズなTextureの切り替えが行われています。

f:id:kazuhironagai77:20210404223541p:plain

f:id:kazuhironagai77:20210404223557p:plain

以下の部分が、Distance blendとは違うやり方で、スムーズなTextureの移行を担当しているようです。

f:id:kazuhironagai77:20210404223613p:plain

以下の部分が遠距離のTextureを担当し

f:id:kazuhironagai77:20210404223628p:plain

以下の部分が近距離を担当してるようです。

f:id:kazuhironagai77:20210404223645p:plain

よって緑のTextureにMacro variationやDistance blendを追加する必要はないと判断しました。

しかし全部理解出来たわけではありません。

以下の部分は何をやっているのか良く分かりません。

f:id:kazuhironagai77:20210404223659p:plain

分かりました。

上記の近距離担当は合っていましたが、遠距離担当は、上記で遠距離担当と思っていたやつと近距離担当を遠距離のMacro VariationでLerpしたものでした。それが最初のLerpです。次のLerpは近距離担当と遠距離担当をカメラからの距離などで混ぜる通常のDistance blendをやっています。

f:id:kazuhironagai77:20210404223714p:plain

これは何をしたいんでしょうか?2.25倍にして0.25で引いて、0から1でClampして?

良く分からないのでグラフにしてみました。

f:id:kazuhironagai77:20210404223732p:plain

  • Lerpはy=25x - 0.25で計算しました。
  • Clampは0以下は0、1以上は1、それ以外はそのままで計算しました。

上記の計算が合っている前提ですが、元の値が0.2未満の場合はもっと黒くなって、0.2以上の場合は白くなる。更に0.6以上ならば真っ白になると言う事でしょうか?全体的に言うと白くなっていると言う事みたいですね。

2.4 Distance BlendでTextureのサイズの設定が逆だったかもしれない。

いつも混乱するので確認します。

f:id:kazuhironagai77:20210404223824p:plain

上のTexCoordのUV値は共に1、下のTexCoordのUV値は共に2です。となると数字が大きくなるほど、Textureは小さくなるみたいです。

Dirtは近距離のTexCoordのUV値は1、遠距離のTexCoordのUV値は0.1なので遠距離の方のTextureが大きくなっています。

遠距離のTextureは大きくするのが正しいので合っています。

3.先週勉強したTutorialの続きをやる

How to INSTANTLY TEXTURE your landscapes in UE4 - Unreal Engine tutorial[2]とThe Secret to Realistic Landscapes in Unreal Engine - UE4 Tutorial[3]を勉強します。

3.1 How to INSTANTLY TEXTURE your landscapes in UE4 - Unreal Engine tutorialを勉強する。

崖用に新たなTextureを追加していました。Rough Rock Wallと言う名前らしいです。

Mega Scanで探しましたが見つかりません。

しょうがないので、似たようなTextureを探していたらありました。

f:id:kazuhironagai77:20210404223855p:plain

あれ、と思ってもう一回、Rough Rock Wallで検索したんですが、検索に引っかかる沢山のTextureの一つとしてこれも出て来ますが、沢山の全く違う名前のTextureと共にしか表示されません。何でなんでしょう?

Importしました。

f:id:kazuhironagai77:20210404223909p:plain

今までは、Mega Scanの方で提供されているMaterialとこのTutorialの合成的なMaterialを作成してそれをDirtとして使用したり、緑の部分はStarter Kitに提供されているMaterialをそのまま使用したりしていました。

今回の崖の部分のMaterialはこのTutorial通りに自分で作成してみようと思います。

3.1.1 崖のMaterialの作成

まず基本のMaterialを作成します。名前はMF_Cliffと名付けました。

f:id:kazuhironagai77:20210404223934p:plain

M_Landscapeに追加しました。

f:id:kazuhironagai77:20210404223949p:plain

Landscape、PaintのTarget Layersを見るとCliffが追加されています。

f:id:kazuhironagai77:20210404224004p:plain

Layerを作成してTextを塗ってみましょう。

f:id:kazuhironagai77:20210404224019p:plain

うわ。絶望的なくらい、タイルタイルしています。直せるんでしょうか?

Macro varianceを追加します。

f:id:kazuhironagai77:20210404224035p:plain

一寸はマシになりました。

f:id:kazuhironagai77:20210404224052p:plain

唐突に思いついたんですが、Macro Varianceのコントラストを下げるために0.5をかけています。この値を変化させたらもっとリアルになるかもしれません。

試してみました。

f:id:kazuhironagai77:20210404224108p:plain

青味がかってちょっとリアルになっている気がします。

f:id:kazuhironagai77:20210404224124p:plain

確認のために真っ赤に設定してみました。

f:id:kazuhironagai77:20210404224147p:plain

f:id:kazuhironagai77:20210404224157p:plain

真っ赤になっていました。

この値はParameterにしてInstanceから調節出来るようにすべきですね。

CliffのMacro Contrastとしてparameter化しました。

f:id:kazuhironagai77:20210404224213p:plain

Distance blendを追加します。

f:id:kazuhironagai77:20210404224229p:plain

凄いスパゲッティコードです。理解しているから読めますが、前もって知識がないとこのコードから何をしているのかを推測するのはかなり大変でしょう。

もっと良い整理方法があるかもしれませんがこのまま行きます。

Parameterも後でInstanceから調整出来る様に作成しました。

f:id:kazuhironagai77:20210404224243p:plain

こんな感じです。

f:id:kazuhironagai77:20210404224258p:plain

流石にTextureがデカすぎですが、タイルタイルしているのは消えています。

近づくとBlendingの酷さや、近距離でのタイルタイル感が全く消えてないのが分かります。

f:id:kazuhironagai77:20210404224312p:plain

後でMaterial Instanceから調整します。

今回は手動でペイントしますのでParlinノイズの部分はパスします。

3.1.2 Tutorial の続き: Texture Sample

一口メモみたいですが、全てのTexture SampleのSampler SourceをShared: Wrapにセットする必要があるそうです。

f:id:kazuhironagai77:20210404224332p:plain

その理由は色々なMaterialを一か所にペイントするとEditorがクラッシュしてしまうからだそうです。しかもこれが原因でクラッシュした時は、UE4は何故クラッシュしたのかを教えてくれないそうです。

Sampler Sourceがそもそも何をするのか不明なのですが、Google先生に聞いても解答を表示してくれません。

途方に暮れてカーソルをSampler Sourceに合わせたら以下の説明文が表示されました。

f:id:kazuhironagai77:20210404224347p:plain

こんな丁寧な説明が出て来るのならどこかでしっかり解説されているはずと探したら

公式のAPISampler Sourceの説明[4]がありました。

f:id:kazuhironagai77:20210404224402p:plain

「Text検索のためのSamplerがどこから来るのかをコントロールします。」今一意味が分かりませんね。

Remarkを読んだらカーソルを乗せた時に出て来た時の説明と全く同じ文章でした。

何となくですが、分かりました。

SamplerSourceはTexture Sampleそのものか、もしくはTexture SampleのTextureをどこに保持するかを決定するためのParameterみたいです。

f:id:kazuhironagai77:20210404224424p:plain

Texture assetを選択した場合、UTexture Addressing settingに保持します。その場合、Sampler slotを消費するため16枚のTextureしか使用出来ないみたいです。

Shard: WrapかShard: Clampを選択した場合は、global samplerに保持されるため、SM5(意味不明)の場合、16枚以上のTextureでも使用出来るみたいです。

それではShard: WrapとShard: Clampの違いは何なのかですが、

見つかりません。

全然探しても出て来ません。

途方に暮れてたら、カーソルを乗せたらまた出て来ました。

f:id:kazuhironagai77:20210404224444p:plain

Clampの方です。

f:id:kazuhironagai77:20210404224500p:plain

違いはWrapがwrap addressingを使用して、Clampclamp addressingを使用するだけのようです。

このWrap addressingとClamp addressingは何となくですがDirect Xの用語のような気がします。

調べたらこのサイト[5]に解説がありました。

UV座標の範囲は通常は0から1ですが、それ以上や以下も指定できます。指定した場合ですが、Wrap addressingはTextureのイメージを繰り返し表示するそうです。Clamp addressingは0以下は0の時の値、1以上は1の値を表示するそうです。

そう言えばOpenGLにも同じ機能がありました。

先程使用した十字のTextureを使用して試してみます。

f:id:kazuhironagai77:20210404224517p:plain

まずTexCoordに3を賭けてサイズを3倍にします。

そしてShared:Wrapにセットします。

f:id:kazuhironagai77:20210404224532p:plain

結果は、

f:id:kazuhironagai77:20210404224547p:plain

十字のTextureのイメージが繰り返し使用されました。

次に

f:id:kazuhironagai77:20210404224600p:plain

変更しました。

f:id:kazuhironagai77:20210404224613p:plain

0と1の値が繰り返し…。

ウーン。1の値が繰り返し使用されているようですが、座標が…。左上が0なんでしょうか?

確認のために1引いてみました。

f:id:kazuhironagai77:20210404224637p:plain

結果です。

f:id:kazuhironagai77:20210404224655p:plain

間違いないですね。左上が0ですね。そして0以下は0の値がずっと使用されている事も確認出来ました。

そう言えば、OpenGLを勉強している時、このTextureに移動、回転、拡大縮小の計算をすると、どうしても自分が予想した結果と違うイメージが出来る時があってかなり悩んだのを思い出しました。

その時の結論は「座標を撮影しているカメラをイメージしてそのカメラが移動、回転していると仮定すると予測通りになった。」でした。

このTexCoordに対して移動、回転、拡大縮小をした場合のTextureの変化も後で調べてみます。

もうSampler Sourceに関しては理解出来ました。クラッシュする理由である「色々なMaterialを一か所にペイントする」とは多分ですが、Texture sampleを16種類以上使用した場合と言う事でしょう。

後、使用している全てのTexture sampleのSampler sourceの設定を、Shared:Wrapに変更しました。

3.1.2 Tutorial の続き: World Aligned Blend

崖のような角度が急な所は計算で見つけて、自動でPaintしたいそうです。そのために使用する関数がWorld Aligned Blendだそうです。

以下の様にして使用するそうです。

f:id:kazuhironagai77:20210404224719p:plain

Tutorialと同じ値をSlop SharpnessとSlop BiasにセットしてAlphaをBase Colorに繋げました。

以下の様な結果になりました。

f:id:kazuhironagai77:20210404224742p:plain

f:id:kazuhironagai77:20210404224751p:plain

Alphaの代わりに、w/Explicit Normalを使用しました。

f:id:kazuhironagai77:20210404224823p:plain

Tutorialではこっちを使用していますが、場合によっては元のalphaの方が良いかもしれません。

Blend Material Attributesを使用して実際のTextureを表示します。

f:id:kazuhironagai77:20210404224846p:plain

Tutorialとはやり方が違いますがこれでも大丈夫でしょう。

以下の結果になりました。

f:id:kazuhironagai77:20210404224902p:plain

うーん。自分でpaintするより綺麗な気もします。実際に使用するかどうかは後で考えます。

TutorialではLayer Blendに新しいLayerを作成してそこに繋げていましたが、全部Layerを新しく作成し直していました。自動でPaintを作成する時は良いですが、時間をかけてPaintしたDataが消えてしまったらかなりショックです。

上記でw/Explicit NormalよりAlphaを使用した方が良いかもと述べましたが、TutorialによるとAlphaの値を直接、Blend Material Attributesのalphaに接続しても使えないそうです。

World Aligned Blendのalphaの値を使用するためには、MatLayerBlend_Standardを使用する必要があるそうです。

MatLayerBlend_Standardを使用する必要があるのではなく、MatLayerBlend_Standardを改良する必要がありました。

3.1.3 MatLayerBlend_Standardの改良

MatLayerBlend_Standardの改良方法をまとめます。

まずコピーを作成します。UE4から提供されている関数を直接改良してはいけません。

f:id:kazuhironagai77:20210404224923p:plain

NormalのAlphaだけ別なInputから取るようにしました。

f:id:kazuhironagai77:20210404224938p:plain

以上です。

3.1.4 Tutorial の続き: World Aligned BlendのAlpha値を使用

改良したMatLayerBlend_Standardを以下の様に接続します。

f:id:kazuhironagai77:20210404224959p:plain

World Aligned Blend のalphaを改良したMatLayerBlend_Standard のAlphaにつなげます。w/Explicit Normalを先程作成したAlpha_Normalに接続します。Blend Material Attributes のAにつなげていたノードをBase Material (MA) Blended Materialに接続します。Blend Material Attributes のBにつなげていたノードをTop Material (MA)につなげます。最後に改良したMatLayerBlend_StandardのOutputをBlend Material AttributesのOutputがつながっていた所につなげます。

結果です。

f:id:kazuhironagai77:20210404225024p:plain

大体何をやっているのか分かりました。

何をやっているのか大体分かると、逆に何でWorld Aligned Blend のalphaでblend出来ないのかが分からなくなります。

分からない時は、分からないヤツにカーソルを乗せてみる。です。

f:id:kazuhironagai77:20210404225041p:plain

Reentrant expressionと書かれています。どういう意味なんでしょうか?

まずProgramming 一般の用語としてReentrant Functionがあるそうです。(正直に告白しますと、知らなかったです。)

このサイト[6]に分かり易い解説がありました。

簡単に説明すればその関数を使用中に別なTaskがその関数を別な目的で使用しても結果が変化しないように作成された関数の事のようです。

うん。それってThread Safeの事?

はい。実は違います。

そこでWikipediaのReentrancy (computing)[7]の解説です。

このサイト「何個か問題がある」と警告が出ているので一端読んだ後、評価を保留にしていたんですがThread SafeとReentrancy (computing)の違いについて簡単で分かり易い具体例が示してあります。

この違いを理解した上で最初のサイト[6]では簡潔にReentrancy (computing)では、Thread Safeと違い、基本的にOne Threadの時代の話でhardware からの割り込みやrecursionなどの場合を想定していると結論づけています。

つまり関数の使用中にhardware からの割り込みやrecursionなどでその関数を別な目的で使用しても実装の結果が変わらないと言うのがReentrant Functionと言うわけです。

Reentrant Function を達成するためには、

  • Global 変数やstatic 変数は使用しない。
  • 関数内のコードは変化しない。
  • Reentrant が保証されていない別な関数は呼ばない。

などの条件を満たす必要があるそうです。

Reentrant expressionに戻りますが、Reentrant expressionと言う表現はUE4でしか使用されていないみたいです。Googleの検索で出て来た結果から推測すると、Reentrancyが保証されない時にReentrant expressionと言っているみたいです。

となると以下の事が考えられます。

  1. World Aligned Blend alphaの計算には、何らかのglobal 変数を使用している。
  2. そのglobal 変数はBlend Material Attributesの計算で値が変わる。
  3. よって、その値が変わったglobal 変数を使用して残りのWorld Aligned Blend alphaを計算する必要がある。
  4. 勿論、正しい値は出てこない。

あくまで推測ですが、そのglobal 変数とはPixel Normal WSでしょう。そしてそのPixel Normal WSの値はBlend Material Attributes内でnormalの計算を行っている時に書き変えられているのでしょう。

3.1.4 Tutorial の続き: 岩と草の間にDirtを追加

これは軽く説明されているだけなので今回はスキップします。

3.1.5 How to INSTANTLY TEXTURE your landscapes in UE4 - Unreal Engine tutorialを勉強してみて

結論を端的に言えば、このTutorialは崖の部分のPaintを行っただけです。

しかしそのやり方が超正統派のPhoto-realistic renderingに則っており、かつ細部における独自の工夫がUE4のMaterialの機能を完璧に理解していないと出来ない方法によってなされているため、最高Levelのtutorialに仕上がっています。

この作者、この若さでここまで出来るのですから、いわゆる天才でしょう。

この作者が作成するTutorialは全てチェックする価値があると思いました。

3.2 The Secret to Realistic Landscapes in Unreal Engine - UE4 Tutorial を勉強する。

Specular Channelの値をTextureのBase Colorに沿って半分にしました。そしてFresnel反射を利用してSpecular Channelの値を下げる箇所と下げない箇所を分けました。

Tutorial通りにやろうと思ったら、緑のMaterial Functionは元のままだし、Dirt は実装が変形し過ぎていまして、簡単には実装出来ない事が分かりました。

どうせ何回かはLandscapeを作成し直すのでその時にこれを実装する事にしました。

4.Foliageの改善(Cull Distanceの使用)

Cull DistanceはLandscape Grass type内で設定出来ました。

f:id:kazuhironagai77:20210404225202p:plain

更に3種類の草を追加しました。

f:id:kazuhironagai77:20210404225219p:plain

f:id:kazuhironagai77:20210404225226p:plain

f:id:kazuhironagai77:20210404225233p:plain

サイズを全部小さくしました。

f:id:kazuhironagai77:20210404225247p:plain

結果です。

f:id:kazuhironagai77:20210404225304p:plain

結構PCが音立てて計算しています。

負担が大きいのでしょうか?

5.水の追加

UIWS Water ManagerとUIWS Water Body を追加しました。

f:id:kazuhironagai77:20210404225328p:plain

こんな感じです。

f:id:kazuhironagai77:20210404225344p:plain

UIWS Water Body を使用しているので、何もしなくても波紋が出来ています。

f:id:kazuhironagai77:20210404225403p:plain

海です。

f:id:kazuhironagai77:20210404225420p:plain

今回はこれで十分です。

6.作成したLandscapeの直したい所

これで実際のProjectのlandscapeを作成使用と思いましたが、結構直したい個所があるのでもう一回だけ練習します。直したい個所を具体的に言うと

  • Landscapeの手直し
  • Material (緑、地面)の作成
  • Foliage の直し

です。

6.1 Landscapeの手直し

川沿いの土手の部分のmeshが荒く、滑らかさが失われています。

f:id:kazuhironagai77:20210404225509p:plain

f:id:kazuhironagai77:20210404225516p:plain

山のメッシュに捻じれた部分があります。

f:id:kazuhironagai77:20210404225534p:plain

f:id:kazuhironagai77:20210404225542p:plain

6.2 Material (緑、地面)の作成

How to HIDE Texture REPETITION in Unreal Engine[1]に書かれていたやり方で草と荒れ地のmaterialを作り直します。

Specular Channelの調節を最初から追加してプラスチック感を減らします。

6.3 Foliageの作成

Foliageの違和感が凄すぎます。違和感の原因を自分で考えると

  • 木がない。
  • 草の生え方が奇妙
  • 花がない。

が考えられます。

更にFoliageに関して言えば、以下の様なPluginもあるのでそれの活用も考えたいと思います。

f:id:kazuhironagai77:20210404225613p:plain

7.Landscapeの作成、もう一度

7.1 Landscapeをexportして修正

海の部分を深くします。

f:id:kazuhironagai77:20210404225640p:plain

もう一度Importします。

f:id:kazuhironagai77:20210404225656p:plain

上記の陸地と海の底の境目をスムーズにします。

f:id:kazuhironagai77:20210404225713p:plain

出来ました。

素早く楽にやるコツはCamera speed を6にセットする事です。

f:id:kazuhironagai77:20210404225727p:plain

今度は川を直していきます。

f:id:kazuhironagai77:20210404225750p:plain

更に全体的におかしい所を直します。

7.2 Materialを作成します。

土から作成します。

Base, roughness, normalで基礎を作成しました。

f:id:kazuhironagai77:20210404225810p:plain

こんな感じです。

f:id:kazuhironagai77:20210404225828p:plain

正直言ってこのTextureでは、あまり目立ちませんが、近づくとタイルが見えます。

f:id:kazuhironagai77:20210404225844p:plain

Macro variationを追加します。

f:id:kazuhironagai77:20210404225900p:plain

f:id:kazuhironagai77:20210404225908p:plain

正直このTextureにdistance blendingが必要とは思えませんが、以下のスクリーンショットを見ると少しはタイルタイルしていますので一応作成します。

f:id:kazuhironagai77:20210404225925p:plain

しました。

数値を適当にいじってみましたがあんまり差が出なかったです。

f:id:kazuhironagai77:20210404225943p:plain

後、並べ方を変えて見ました。

f:id:kazuhironagai77:20210404230015p:plain

少しは見やすくなったと思います。

Specular channelを調整します。

有りです。

f:id:kazuhironagai77:20210404230045p:plain

無しです。

f:id:kazuhironagai77:20210404230103p:plain

実装部です。

f:id:kazuhironagai77:20210404230118p:plain

有りと無しを比べると有りが圧倒的に良いですが、それでもまだプラスチックみたいです。もう少し下げてみます。

0にしました。正直0でも違和感ないですし、地面が光っているよりリアルに近い気がします。

f:id:kazuhironagai77:20210404230155p:plain

Play中の画面です。

f:id:kazuhironagai77:20210404230215p:plain

もう少し地面がデコボコしているとリアルな気がします。Displacement mappingを追加するか、Landscapeで地面に微妙な凹凸を形成したいです。

Landscapeから小さな凹凸を付けてみました。

滅茶苦茶リアルに感じます。見た目もリアルですが、移動するとデコボコの地面を走っているため、画面が微妙に上下します。それがリアル感を出しています。

f:id:kazuhironagai77:20210404230233p:plain

Landscapeから地面をもっとボコボコにしてみました。

f:id:kazuhironagai77:20210404230249p:plain

ちょっとデコボコ過ぎました。

f:id:kazuhironagai77:20210404230307p:plain

直します。

f:id:kazuhironagai77:20210404230321p:plain

うーん。やっぱりDisplacement mappingもあった方がよさそうです。ですがDisplacement mappingの勉強を今からやるのはちょっときついので来週にします。

7.3 海を作成します。

川や池、沼地の場所を先に把握したいので海を先に作成します。

こんな感じです。

f:id:kazuhironagai77:20210404230346p:plain

こっちの川がまったく水が流れていないので直します。

f:id:kazuhironagai77:20210404230402p:plain

水は流れる様に成りましたが崖の部分のMeshがグチャグチャです。

f:id:kazuhironagai77:20210404230420p:plain

直します。

f:id:kazuhironagai77:20210404230501p:plain

出来るだけ直しました。

f:id:kazuhironagai77:20210404230520p:plain

湿地帯を作って行きます。

f:id:kazuhironagai77:20210404230537p:plain

微調整を行います。

f:id:kazuhironagai77:20210404230553p:plain

正直しない方が良かったかもしれません。

7.4 崖を追加します。

地面をMaterial Functionにします。

f:id:kazuhironagai77:20210404230613p:plain

崖のMaterial Functionは3.1で作成した物をそのまま使用します。

更に3.1のTutorialで習ったWorld Aligned Blendのalpha値を使用した崖のPaintを使用しました。

f:id:kazuhironagai77:20210404230629p:plain

こんな感じです。

f:id:kazuhironagai77:20210404230651p:plain

近づくとこんな感じなので微調整をします。

f:id:kazuhironagai77:20210404230730p:plain

Material Instanceから微調整して、近距離では以下の様、

f:id:kazuhironagai77:20210404230747p:plain

遠距離では以下の様に、

f:id:kazuhironagai77:20210404230805p:plain

設定しました。

7.5 緑(草)のMaterial を追加します。

Starter KitにあったM_Ground_Grass を元に作成した、緑(草)のmaterialですが、見直したら、黄色と緑のParlin noiseなんかも使用していてまだ理解出来てない箇所がありました。のでそのまま使用する事にします。

f:id:kazuhironagai77:20210404230840p:plain

一生懸命自分で塗りました。

f:id:kazuhironagai77:20210404230859p:plain

7.6 Foliageを追加します。

これを使います。

f:id:kazuhironagai77:20210404230921p:plain

以下のMaterialを使用しました。

f:id:kazuhironagai77:20210404230937p:plain

f:id:kazuhironagai77:20210404230944p:plain

f:id:kazuhironagai77:20210404230951p:plain

f:id:kazuhironagai77:20210404230959p:plain

こんな感じに仕上がりました。

f:id:kazuhironagai77:20210404231016p:plain

今週はこの辺で止めておきます。

残りは来週やります。

8.まとめと感想

今週は、先週作成したLandscape の直し、先週やり残した2つのtutorialの勉強、そしてもう一度、新しいLandscapeを作成しました。

Landscape の直しでは以下の事をやりました。

  • Material instanceの作成。Material instanceを作成するとCompileしなくてもparameterの値を変えられるので3d view portを見ながら微調整が出来る。非常に便利。
  • Displacement Mappingについて。来週もっと勉強してLandscapeに使用する予定。
  • M_Ground_Grassの実装についての勉強。M_Ground_GrassStarter kitに付属のmaterial だか、実装方法が複雑で色々な機能が不明瞭な形で実装されている。(Macro varianceDistance blendingPerlin Noiseなど)

先週、やり残した2つのTutorialでは以下の事を勉強しました。

  • Texture SampleSampler Sourceについて
  • World Aligned Blendを使用して崖を見つける方法について
  • World Aligned Blendalpha値を使用する方法とReentrant expressionについて
  • Cull Distanceを使用する事で、Foliageの表示される範囲を自然かつPCに負担のないようにする方法について
  • UIWSを使用して水を表現。

もう一度、新しいLandscapeを作成した時に使用した機能です。

  • Specular Channelの値をあえて変更する。
  • Interactive Open world foliageを使用。

UE4のmaterialはC++でもShader 言語でも書けずBPを使用する事を強制される割に、3d Graphicsの数学と知識を総動員しないと理解出来ない、見た目とその難しさが真逆の分野と言う事が分かりました。更にmaterialの最適な値を見つけるためには実際の3D画面を見ながら細かい微調整が必要であり、芸術性が大きく要求される分野でもあります。

来週は以下の事をやろうと思っています。

  • Displacement mappingの実装
  • 針葉樹用の緑と沼用の地面のMaterialの追加
  • 沼の整理
  • ゲーム内のlandscapeの作成。

以上です。

今週も疲れました。

8.参考文献(Reference

  1. Unreal Sensei. (2020a, August 7). How to HIDE Texture REPETITION in Unreal Engine - UE4 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=yCRzOdo4b68
  2. Unreal Sensei. (2020b, August 8). How to INSTANTLY TEXTURE your landscapes in UE4 - Unreal Engine tutorial [Video]. YouTube. https://www.youtube.com/watch?v=mP8eHwVEA0o
  3. Unreal Sensei. (2020c, August 10). The Secret to Realistic Landscapes in Unreal Engine - UE4 Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=UIycCZl4lYE
  4. Epic Games. (n.d.). SamplerSource. Unreal Engine Documentation. Retrieved April 4, 2021, from https://docs.unrealengine.com/en-US/API/Runtime/Engine/Materials/UMaterialExpressionTextureSample/SamplerSource/index.html
  5. Mocrosoft, White, S., Satran, M., & Koren, A. (2017, February 8). Texture addressing modes - UWP applications. Microsoft Docs. https://docs.microsoft.com/en-us/windows/uwp/graphics-concepts/texture-addressing-modes
  6. (2018, April 26). Reentrant Function. https://www.geeksforgeeks.org/reentrant-function/
  7. Wikipedia contributors. (2021, February 4). Reentrancy (computing). Wikipedia. https://en.wikipedia.org/wiki/Reentrancy_(computing)

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する  マップの作製など Part 3

f:id:kazuhironagai77:20210328225746p:plain

<前文>

日本人が無邪気に信じる言論の自由アメリカにもないです。

英語の勉強方法に一寸だけ関係する内容を書いたりしていますが、結構な確率で英語の勉強をしている日本人で、アメリカが全ての点で日本よりも優れている国であると信じてる人に会います。10年以上アメリカに住んでいた私がハッキリ言いますが、そんな事は無いです。

言論の自由に限っても、アメリカの方がタブーは多い位です。今回、アジア系を狙った殺人事件がAtlantaで起きましたが、この事件の犯人は「このアジア人達が自分を性的に興奮させる可能性を起こすから殺した。」と動機を述べ、かつその殺された人達の職業が知れ渡った時、ほとんどのアメリカ人が「それなら殺しても仕方ないね。」と思っていたんです。

まずある種の女性を見て性的な興奮をするかどうかは個人の問題で、その人自身の責任でしょう。その責任を他人かつ一部の人種のせいにして、その人種の人達を殺す事はRacism以外の何物でもないです。それをみんなアメリカ人は分かっていたんですが、アジア系のアメリカ人はその差別を受け入れろと言うある種の忖度をアジア系に強制しているんです。

この事件がRacismであるとはっきりと述べたのは、現在、私が知る限りでは黒人のコメンテーター、一人だけです。タブーに切り込むのは非常に勇気が要りますし、彼にしたって何でアジア人のために自分のキャリアをリスクに賭けてまでそんな事を言うのかかなり悩んだはずです。

そんな中で、中国政府がアメリカ政府に面と向かって「人の国の人権問題にクビを突っ込む前に自分の国の人権問題、解決しろよ。」と言ったのは、ハッキリ言って勇敢だと思いました。

あるVtuberに対する嫌がらせで中国がかなり嫌いになっている私ですら、今回の中国政府の発言は肯定的に捉えるしかない位ですので、アメリカ国内における中国政府の評価は、アメリカのタブーに真正面から挑戦したとして、本音の部分では好意的に受け止められるでしょう。

勿論、今回の件だけを切り取って、米国の没落と中国の勃興が始まったと言うつもりはありません。これは中国人自身も良く言うように「中国人は口だけ。言う事は凄いが全然実行が伴わない。」だけかもしれないからです。しかし口だけだってアメリカのタブーに真正面から挑戦した事は評価すべきでしょう。

難民問題と日本の深謀

読書病と言う病気が本当にあるのか知りませんが、あるのなら中学時代の私は読書病でした。買った文庫本だけで800冊以上、記憶にあるだけで最低2回は読み直していました。好きな本なら数十回は読んでいましたし、それでももっと本が読みたくて本屋で本を買うフリして一冊丸々立ち読みしてしまう事もよくやりました。

その時の友達の親で読書が趣味の方が居たのですが、その人は私にどんどん本を貸してくれました。その時に読んだ本で、多分80年代位に書かれたPHPの文庫本だったと思うんですが「将来、中国から大量の難民がやって来て日本が崩壊すると恐怖を煽っている人がいるが、日本がお金持ちに成れたのは科学技術を用いて人を傷つける武器ではなく、人の役に立つ商品を作ったからだ。その事を中国に教え、その方法も中国に教えれば、中国自体がお金持ちに成って、敢えて日本に難民として来たいとも思わなくなる。」と書いてありました。

また大量のメキシコ人が国境を越えてアメリカに侵入しようとしていると言うニュースを聞いてその事を突然思い出しました。前に不法に侵入した人達は、バイデン政権下で特別にアメリカ人に成れる事が判明したので更なる不法移民がアメリカに押し寄せる事は間違いないです。

今、日本人で中国から大量の難民が来る事を恐れている人は、ネトウヨと呼ばれる一部の夢の世界で生きてる人達を除いてほとんどいないでしょう。むしろ日本人の方が中国に行って働きたいと思うくらいです。それは中国が豊かになったからです。そして中国が豊かになったやり方は、まさしく科学技術を用いて人の役に立つ商品を作ったからです。

当時の日本人はそこまで考えて中国に技術を教えていたんです。

自分の周りの国を、暗殺やクーデターのようなダーティな手段を使用してでも潰して常に弱くしておくアメリカと、周りの国にお金の稼ぎ方を教えて豊かにした日本、難民問題に関してはどちらが正解だったのでしょう。

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

<本文>

1.今週の予定

今週は、

  • DocumentのWater、Foliage Tool、Fog Effect、そしてHierarchical Level of Detailを読みます。
  • 日本語の資料で関係している箇所もチェックします。
  • UIWSの使用方法も勉強します

f:id:kazuhironagai77:20210328225957p:plain

  • Paintの見た目がオカシイ所を直します。(出来ればlayerをもっと増やしたいです。)
  • Grass toolで2種類以上の草を生やします。(見た目の違和感も無くしたい。)
  • Map1のLandscapeを完成させます。

以上をやっていきます。

WidgetのBPの整理、そしてEffectの勉強は時間があったらやります。

2.Documentの勉強

2.1 Foliage Tool

一番、先週勉強した分野に近いFoliage についてのDocumentを最初に読む事にしました。

使用しているVersionが4.26でした。4.26からFoliageの配置が変わっています。(正確には4.25から変わっていました。)

f:id:kazuhironagai77:20210328230100p:plain

2種類のMeshが追加出来るとの説明がありました。

Actor FoliageとStatic Mesh Foliageです。

f:id:kazuhironagai77:20210328230115p:plain

Static Mesh FoliageがInstance (instanced static mesh component)を使用した場合に該当しているのでしょうか?

  • 先週のBlogを読み直していたらInstanced static mesh component InstanceStatic meshから作成されたそれぞれのObjectInstanceと呼んでいました。この二つは全く違うモノなのでInstanced static mesh componentを言うときはInstance (instanced static mesh component)と呼ぶ事にします。
  • Instanced static mesh componentは以下に示したイメージのような大量のstatic meshinstancePCに負担をかけずに表示する時に使用するClassの事です。

f:id:kazuhironagai77:20210328230154p:plain

Size、Density、Erase Densityについての解説がありました。

f:id:kazuhironagai77:20210328230221p:plain

Sizeが300の時です。

f:id:kazuhironagai77:20210328230237p:plain

Sizeが1000の時です。

半円の大きさをコントロールしているのが分かります。

f:id:kazuhironagai77:20210328230252p:plain

次はDensityについてです。

Sizeが1000でDensity 0.5 で試します。

f:id:kazuhironagai77:20210328230308p:plain

生成される岩の位置は毎回変わりますが、岩の数は常に2個です。

今度は、Densityを1にします。

f:id:kazuhironagai77:20210328230330p:plain

今度は生成される岩の数が3つになりました。

Densityが高いほど、生成されるinstanceの密度が高くなるようです。

Documentを読むと1の時にそれぞれのMeshのMesh Properties に書かれているMaxのDensityに成るように設定されていると書かれていました。

これの事でしょうか?(1Kuuと言う単位は知りませんが、多分1 kilo Unreal Unitの略でしょう。)

f:id:kazuhironagai77:20210328230351p:plain

試しに10に変更してみます。

以下に示した様に大量の岩が出現しました。

f:id:kazuhironagai77:20210328230408p:plain

定量的に判断したいので2にセットして試してみます。

以下に示した様に1の時の2倍の6個の岩が出現しました。

f:id:kazuhironagai77:20210328230423p:plain

何で生成するためのInstanceの数をコントロールするParameterが2つもあるのか分かりませんが、Densityの使用方法は理解出来ました。

Erase Densityについてです。

これは、Ctrl + Shift + クリックで生成したInstanceを消す時の割合を決定するための値のようです。

0で試すと半円内の全部のInstanceが消えます。1の時は全く消えません。0.5の時は6個の内2個消えました。残り2個になったら消えなくなりました。

解説を読んだら以下の様な説明がされていました。

f:id:kazuhironagai77:20210328230451p:plain

これを読むとInstanceを消すと言うより、濃すぎるDensityでpaintした箇所を薄くするために使用するみたいです。濃く塗ってしまった箇所を初めからやり直す必要が無くなると書かれています。

次はFilterについての解説です。

f:id:kazuhironagai77:20210328230523p:plain

Filterで選択したタイプのActorにのみFoliageを追加する事が出来ます。

それだけです。

Toolの中で赤枠で囲った機能の解説です。

f:id:kazuhironagai77:20210328230540p:plain

解説を見ないで覚えてるだけで説明してみます。

  • SelectInstance1個だけ選択する時に使用するはずです。
  • Paintはいつも使用するやつです。
  • Reapplyは全く分かりません。
  • SingleInstanceを一個だけ追加します。
  • Fillは選択したlandscape全体にInstanceを追加します。
  • Eraseは多分Erase Densityと同じでしょう。

解説を見ます。

Reapplyは既にPaintした箇所のparameterを変更する時に使用するそうです。

Fillの説明が以下の様に書かれていましたが良く分かりませんね。

f:id:kazuhironagai77:20210328230607p:plain

後は、大体合ってました。

次はSelectで選択したInstanceに対してどんなActionが取れるかの説明がされていました。

End Keyだけ良く分かりません。Instanceを接地する機能なんでしょうか?

Paint、Reapply、SingleのActionについての解説がありましたが、大体知っている事なので省略します。

Fillの解説でFillはLandscape上をInstanceでFillするのではなく、Statice Mesh上をInstanceでFillすると解説されてました。

Erase Toolは選択した箇所を全部消すようです。Erase Densityは指定したDensityに減らすので機能としてはReapplyに近かったです。

Cullingについてです。

f:id:kazuhironagai77:20210328230627p:plain

遠くのMeshはCullingされて作成されません。その距離を指定するのがMaxのようです。しかし01でいきなりCullingをすると見た目が変になるのでCullingを始める距離をMinで指定して完全にCullingでmeshを消す距離をMaxで指定するようです。

LODについてです。

LOD自体の細かい設定を理解していないので、パスします。

Lightingについてです。

Lightingで注意しなければならないパラメーターは2つだそうです。

まずLight Map Coordinate Indexの値とUV channelの値を同じにする必要があるそうです。

f:id:kazuhironagai77:20210328230649p:plain

f:id:kazuhironagai77:20210328230658p:plain

Mesh Editorで確認しましたが、同じ値に初めからセットされているようです。

次はLight Map Resolutionです。

f:id:kazuhironagai77:20210328230716p:plain

f:id:kazuhironagai77:20210328230723p:plain

この数字は小さくないといけないと説明されていました。

その理由は(Defaultでは100個の)InstancesのShadow mapを一つのクラスターにして保存するのでそのクラスターのTextureのResolutionが4094x4096を超えないようにするためだそうです。

64 x 10 = 640 なので十分小さいでしょう。

Foliage Scalabilityについてです。

Foliage Scalabilityとは何ぞやと言う事ですが、FoliageにあるStatic Mesh Foliageの使用方法の説明のようです。

f:id:kazuhironagai77:20210328230744p:plain

先週、Landscape Grass Typeの使用方法について学んだので、Static Mesh Foliageの使用方法も勉強しておきましょう。

Static Mesh Foliageを作成したらMeshにStatic mesh を指定して、Enable Density Scalingをチェックします。

f:id:kazuhironagai77:20210328230824p:plain

作成したStatic Mesh FoliageをPaintのAdd Foliage Typeに追加します。

f:id:kazuhironagai77:20210328230841p:plain

Paintで塗った後です。

6個の岩があります。

f:id:kazuhironagai77:20210328230902p:plain

Playしてゲームを実行します。

@を押してコマンド入力可能にします。

foliage.DensityScale 0.1 を入力します。

f:id:kazuhironagai77:20210328230920p:plain

岩の数が1個に減りました。

こうやって使用するそうです。

以上でした。

2.3 Water

次は水のDocumentを読んでみます。

来ました。

Water pluginの説明です。

f:id:kazuhironagai77:20210328230941p:plain

これの使い方が勉強したかった。

まず、ビデオがありました。35分もあります。

f:id:kazuhironagai77:20210328230958p:plain

見ました。

高等なテクニックは全く理解出来ませんでしたがLandscapeを作成した後、

f:id:kazuhironagai77:20210328231013p:plain

をドラックして追加すれば海が出来るみたいです。

更に、

f:id:kazuhironagai77:20210328231027p:plain

を追加すれば湖が出来き、

f:id:kazuhironagai77:20210328231041p:plain

を追加すれば川が出来るみたいです。

取りあえず、これを試してみます。

何か出来るんですが、サンプルの様にLandscapeの形状が勝手に変わってくれません。

自分でLandscapeのScriptで形状を変化させる必要があります。

凄い調べたら答えらしきものが分かりました。

Landscapeを作成する時に、以下に示したEnable Edit layersをチェックする必要がありました。

f:id:kazuhironagai77:20210328231105p:plain

やっと以下のような海、湖、そして川を含んだ地形を作成出来ました。

f:id:kazuhironagai77:20210328231122p:plain

見た目もしょぼいし、川と海や川と湖のつなぎ目も変ですが、最初の一歩としては十分です。

それではDocumentを読んでいきます。

Enabling and Using Water

Water pluginを使用出来る状態にする手順が説明されています。

Water Tool Features

このpluginに付属のToolについてです。具体的なToolの使用方法はこの後で解説しています。

Water Body Actors and Spline-based Tools

Water Body Actorには以下の種類があります。

f:id:kazuhironagai77:20210328231146p:plain

先程使用したのは、Ocean、Lake、そしてRiverです。

Water Body Actor の特徴はa spline-based workflowです。

Water Body Actorは以下の事が出来ます。

  • 移動、回転、拡大縮小、そして複製。
  • Alt + ドラッグで新しいSpline 点を作成。
  • 水の流れるスピード、深さそして音をそれぞれの点で調節。
  • 水の特徴を調節するために、それぞれの点からメニューにアクセス出来る。
  • Landmass pluginにある非破壊のLandscape Edit Layersを使用する事で自動的にLandscapeに干渉出来る。

最後のLandscape Edit layersを使用するためには、Landscapeを作成する時にEnable Edit layersをチェックする必要があります。

Landmass Pluginは既にチェックされているので使用するために時に何かをする必要はないです。

f:id:kazuhironagai77:20210328231215p:plain

Gerstner Waves

正直、初めて名前を聞きました。これは波の動きを表す方程式のようです。

この方程式については後で詳しく調べます。

Fluid Simulation and Gameplay Physics

波にさらわれた浮遊物や波の波紋、水飛沫、そして泡を作成するための機能のようです。

表示されているイメージにGIFと書かれれていたのでクリックしたらイメージが消えてしまいました。

force impulsesについての説明があります。浮遊物を表すactorそれぞれが持つ値で、その浮遊物の掛かる力を表すパラメーターだそうです。でも実際は良く分かりません。使って見ないと。今回はこんなパラメーターがあるよ。位の理解にしておきます。

Water Mesh Actor

全ての海、湖そして川は一枚のWater Mesh Actorで作られているそうです。

川と海の様に重なっている箇所は一枚のメッシュを共同で使用するみたいです。本当でしようか?

先程自分で作成したヤツの川と海のつなぎ目をBrush Wireframeにして表示してみました。

f:id:kazuhironagai77:20210328231237p:plain

川と海のメッシュの大きさは違いますが、確かにつながっています。(赤枠で囲った部分)

GIFのアニメーションがこのWater Mesh Actorの特徴を分かり易く説明していました。

簡単に説明し直すと。

最初は以下の図の様に成っています。

f:id:kazuhironagai77:20210328231255p:plain

中心と端のVertex以外のvertexが以下の図の様に移動します。

f:id:kazuhironagai77:20210328231311p:plain

これで波が起きる状態を表します。

天才的なアイデアです。

Vertex Shaderでこの動きを管理しているんでしょうか?

先程の海と川と湖を作成したプロジェクトでWater Mesh Actorを調べたらありました。

f:id:kazuhironagai77:20210328231327p:plain

このクラスのパラメーターで重要なヤツの解説がされています。

一回も使った事がないパラメーターの役割を説明されても理解出来る訳在りません。スキップします。

一応以下のパラメーターについての説明があったとだけまとめておきます。

  • Force Collapse Density LevelTile SizeExtent in TilesTessellation FactorLOD ScaleFar Distance Material、そしてFar Distance Mesh Extentです。

Rendering Features

Renderingの中で重要な部分を説明している様です。

Underwater Post Process materialは、水中からの景色を担当しているみたいです。

川と海の水の繋がりについて

川のActorが担当しているみたいです。

このDocumentに例として紹介されている川と海の繋がっている部分は非常にきれいです。

私が作成したのを以下に示しますが川と海の違いがはっきりしています。

f:id:kazuhironagai77:20210328231352p:plain

これって直せるんでしょうか?

Caustics generation tools(水面のキラキラを作成するツール)

流石にこれをいじるレベルにはまだ達していませんので今回はスキップしておきます。

Water Bodies

海、湖、川などの紹介です。

以上です。

2.4 Fog Effect

こんな沢山のDocumentの集まりでした。

f:id:kazuhironagai77:20210328231418p:plain

Level designに霧は必要ですが、霧を追加するのは最後で良いので今回の勉強はパスしておきます。

2.5 Hierarchical Level of Detail

Hierarchical Level of Detail ってHLODの事だったです。何か勘違いしていました。Level designの高レベルな(つまり抽象的な)構造の説明だと思っていました。

これも今回はスキップします。

3.Landscapeの作成に関しての勉強:日本語資料

マテリアルデザイン入門」にstatic mesh の代わりにInstance (instanced static mesh component) を使用する事でmemoryの負担を大幅に減らす事が出来る話が普通に解説されていたと思ったら、単なるMaterial instanceの作成方法でした。全く違う話でした。

Landscapeに関係している13章から15章まで軽く読みました。それぞれの話は大変興味深いですがMaterial 中心の話なのでmaterialの勉強する時にじっくり読む事にします。

一番重要なのは、遠距離と近距離でTextureのサイズを変える方法ですが、

個人的に特に面白いと思ったのは、

  • World Position Offsetノードの解説。
  • Two Side Signノードと法線の向きの関係を図で解説した所

でした。

World Position OffsetもWater Mesh ActorもVertex Shader内で頂点を動かしているんでしょうか?

Two Side Signノードと法線の向きに関してですが、法線は物理を勉強してない人には馴染みのない概念です。法線に対して何かしたら予想と違う挙動をして困ってしまった。と言う経験をした人は結構多いと思います。コラム内で法線の挙動を表すために使用されている図は、法線の挙動を非常に分かり易くかつ正しく可視化していて、驚嘆しました。

法線に関してですが、昔、Vertex shader内で頂点の法線を正規化(normal vectorをnormalize!?)するとFragment shader(direct xではpixel shader ?)内でその正規化した法線を元にpixel毎の法線が生成されますが、その法線は単に正規化した頂点の法線を補間しただけで、pixel毎の法線が正規化した訳ではないのでFragment Shader内でpixel毎の法線をもう一度正規化すると影の付き方がこんなに違うと立方体を例にして見せた時がありました。

興味すら持ってもらえなかったです。

この法線の図も多分、興味持って貰えないのでコラム送りになったのでしょうが、私的には読んでいて大興奮する箇所でした。

4.UIWSの使い方について

せっかくWater pluginの使い方を覚えましたが、今作成しているゲームのVersionは4.24なのでwater pluginは使えません。

代わりにUIWSを使用しようと思います。

f:id:kazuhironagai77:20210328231524p:plain

このPluginのdocumentを見たのですがあまり詳しい説明はないですね。YouTubeには何個かTutorialがありました。

取りあえずInstallしてYouTubeのtutorialを見てみます。

何個かYouTubeのtutorialを見た所、以下のUIWS ManagerをLevel内に配置して

f:id:kazuhironagai77:20210328231550p:plain

更にUIWS Water Bodyを配置すれば、水面が出来るみたいです。

f:id:kazuhironagai77:20210328231604p:plain

こんな感じでした。

更に、Third Person Character が水に干渉出来るようにThird Person CharacterのMeshのRenderの以下の設定を変更しました。

f:id:kazuhironagai77:20210328231619p:plain

水中を歩いていると水しぶきや波紋が見えます。

f:id:kazuhironagai77:20210328231634p:plain

これだけしか分かりません。

正直、water-pluginを見た後だと、かなりしょぼく見えます。

そうだ提供されているサンプルを見てみます。

View OptionのShow Plugin Contentをチェックして

f:id:kazuhironagai77:20210328231650p:plain

UIWS Contentを表示させます。

f:id:kazuhironagai77:20210328231706p:plain

その中にあるUIWS Demo Levelを開きます。

f:id:kazuhironagai77:20210328231722p:plain

水飛沫が表現されています。

f:id:kazuhironagai77:20210328231736p:plain

Water pluginを見た後だからかもしれませんが、正直な感想を言うと、水飛沫じゃなくてプラスチックの削りカスが生成されているみたいです。

f:id:kazuhironagai77:20210328231754p:plain

キャラを滝に飛び込ませるとしっかり水飛沫がキャラに反応しています。

反対側の滝にも飛び込んでみました。

f:id:kazuhironagai77:20210328231810p:plain

こっちの滝はかなり滝でした。水飛沫の量が多すぎるとプラスチック感が出るみたいです。

生成された水面を見ています。こっちはかなり水面しています。

f:id:kazuhironagai77:20210328231826p:plain

水面下からの画像です。

f:id:kazuhironagai77:20210328231840p:plain

これも水面下から見てる感は凄いですがWater pluginと比較すると一寸落ちる気がします。

まあ、文句ばかり書きましたが、十分凄いですので、これを使用して海と川を作成する事にします。

川も作成してみました。

f:id:kazuhironagai77:20210328231900p:plain

川の頂点を増やす方法は、頂点を選択した状態でalt + ドラックでした。Duplicateを作成するのと同じ要領でした。

Third Person Characterと川が干渉しません。

f:id:kazuhironagai77:20210328231915p:plain

製作者が結構真剣にUserからの質問に答えてると聞いたので、同じ疑問を持った人もいるかもと思い調べたらありました。

f:id:kazuhironagai77:20210328231931p:plain

Uiws boyのBPを開いて見るとRippleとコメントに書かれた箇所でApply Force at Locationが使用されていました。

f:id:kazuhironagai77:20210328231945p:plain

この関数の使用方法が分かれば川にキャラが侵入した時に波紋や水飛沫が発生するように出来そうです。

この関数と川との干渉は後で検討します。

滝も川を曲げて作成しました。

f:id:kazuhironagai77:20210328232002p:plain

正面から見るとかなり凄いですが、横から見ると単なる線です。

f:id:kazuhironagai77:20210328232027p:plain

先程の水飛沫ですが、Particle systemで作成していました。

f:id:kazuhironagai77:20210328232043p:plain

プラスチックの破片が飛んでいるみたいと散々悪口言いましたが、Particle systemから自作するのは大変なのでこれを使用する事にします。

以下の水飛沫用に以下のParticle が提供されていましたので、これらも使います。

f:id:kazuhironagai77:20210328232059p:plain

残りは川や海を作成しながら勉強するようにします。

5.Landscapeの直し:準備編

5.1 Tutorialで勉強

偶然でしょうがYouTubeのお勧めに「How to HIDE Texture REPETITION in Unreal Engine - UE4 Tutorial」と言うLandscape作成のビデオが表示されていました。そこでこんな駄目なLandscapeを制作していませんか?と紹介されていた駄目なLandscapeが、私が作成したLandscapeをそのまま載せたんじゃないかと言うくらいそっくりでした。

そのビデオで紹介されていた駄目なLandscapeの例

f:id:kazuhironagai77:20210328232137p:plain

先週、私が作成したLandscape。あんまりにもそっくり。

f:id:kazuhironagai77:20210328232155p:plain

お茶飲みながら見てたんですが、もう少しでこぼすとこでした。

これは全部見るしかないと思い、ちょっとそのTutorialで勉強する事にしました。

  • 質の高いTextureを使用する。Mega ScanTextureを使用する。
  • Macro variationのあるtextureを使用する。
  • Distance blendを使用する
  • Materialを変化させる。

などが解説されていました。

うん。

このTutorialに沿ってやり直しますか。

やり直しますが、それはLandscape作成の基本を勉強すると言う意味でやり直します。Photo realistic renderingにシフトする訳ではないです。

マンガの絵がオカシイと言われ続けウン十年ですが、写実的に正しくなくてもマンガは売れています。

ゲームはほとんどやらない私ですがアニメや漫画は良く見ます。アニメや漫画でよく言われるのが「キャラは記号である」と言う事です。あるキャラは“強い”という記号を表している。別なキャラは“美人”という記号を表している。と言う意味です。

この記号と言う概念は、キャラだけでなくその世界観にも繫がります。

例えば、カイジと言うマンガは独特の世界感があります。その作者の独特な絵柄がその独特な世界観を表す記号になっていて絵柄をパッと見るだけで読者は、ああ「カイジの世界なのか」と納得します。

写実的に正しい描写はこの物語において大切なそのキャラが持つ記号やそのゲームが持つ世界観を曖昧にしている気がします。

その辺の現実は受け入れた上で勉強します。

5.2 Landscapeもう一度

この作者の前のtutorialで最初からLandscapeを作成しているのがあります。Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4です。それで勉強する事にします。ただそのTutorial、4時間もあります。取りあえず最初の10分だけ見てみます。

10 分だけ見ました。本当の初心者向けのTutorialです。Unreal Engineのinstall 方法から説明していました。

Mega Scanを使用するやり方は2時間後から始まっています。しかも5分で終わっています。その後からLandscapeの作成が始まっていますのでこの後半の2時間だけ見れば十分みたいです。

ですが、復習も兼ねて一応全部見てみます。

5.3 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:前半部

お菓子を食べながら映画でも見る感じで軽く見ました。

それぞれの章で知らなかった事や、大切だと思った事を以下にまとめました。

User Interface

この赤で囲った画面の部分の名前知っていますか。3D viewportと言うらしいです。

f:id:kazuhironagai77:20210328232310p:plain

4.25からModeがtoolに移行してModeのある場所にはPlace Actorが配置されているんですね。私は今しばらく4.24でやっていくのでこの辺は後の楽しみとします。

このオレンジの三角をクリックすると、タブが表示されるのも知りませんでした。

f:id:kazuhironagai77:20210328232332p:plain

こんな感じです。

f:id:kazuhironagai77:20210328232346p:plain

<3D Navigation>

Standard NavigationとGame style Navigationの二つの操作方法があるのは知りませんでした。自分がどんな方法で操作しているのかもう意識していないので分かりません。多分全部知っているでしょう。

<Viewport Settings>

この部分の説明です。

f:id:kazuhironagai77:20210328232428p:plain

この意味知っていますか。

f:id:kazuhironagai77:20210328232446p:plain

ExposureってHDRの事だと思うんですがLevel designの時それをOn Offするためだそうです。

<Manipulating Object>

Gを押す事で、以下に示したようなeditorでのみ表示されるウィジェットの表示を消す事が出来るそうです。  

f:id:kazuhironagai77:20210328232533p:plain

これも知りませんでした。

<Intro to Materials、Physically Based Rendering、Migrating and Downloading Unreal Assets>

特になかったです。

<Advance Materials>

色を管理するTextureのみsRGBにチェックを入れます。

f:id:kazuhironagai77:20210328232624p:plain

Normal map や Roughnessを管理するTextureはsRGBのチェックを外します。

何となくは覚えていましたが、念のために記録しておきます。

Normal mapにはDirect XタイプとOpenGLタイプの2種類があってUE4はDirect Xタイプを使用しています。

OpenGL用のNormal mapを使用する場合はTexture のFlip Green Channelにチェックを入れます。

f:id:kazuhironagai77:20210328232646p:plain

正直この事は全く知りませんでした。

<Creating a 3D asset>

特にないです。

<Reflections and Post Process>

Screen space reflection とその停止方法が知らなかったです。

Screen space reflectionの停止方法について解説します。

Post Process Volumeを追加します。(下の図はView modeでReflectionを選択しています)

f:id:kazuhironagai77:20210328232735p:plain

Rendering FeaturesのScreen Space ReflectionsのIntensityをチェックします。

f:id:kazuhironagai77:20210328232752p:plain

値を0にセットします。

Screen space reflectionがOffになりました。

f:id:kazuhironagai77:20210328232809p:plain

床に移っていた家が消えました。

<Lighting: Static vs Movable>

特にないですが、Lightに関しての自分の知識が正しかった事の確認は出来ました。

<Lighting: Types of Lights>

Rect lightを知らなかったです。

Sky lightとatmospheric fog の関係を説明していたのですが良く理解出来なかったです。この辺はLighting の勉強する時にしっかり復習します。

Static lightingとStationary lightingの具体的な違いを知りました。Stationary lightingはDynamic shadowをcast出来ます。

2020-11-08のブログ

f:id:kazuhironagai77:20210328232857p:plain

と書いていましたが、この辺の理由もStatic lightingとStationary lightingの違いから説明出来そうです。

<Lighting: Build Lighting - realistic interior>

これは、実際に提供されているsampleをdownloadして自分で試さないと完全な理解は出来ませんね。

建築業界の人には必須かもしれませんが、あんまり興味ある話ではないです。

5.3 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:Mega Scanの使用

地面に岩のTextureがタイルのように繰り返し貼り付けられているのを目立たなくするためには、まず「質の高いTextureを使用すべき。Mega ScanのTextureを使用すべき。」と「How to HIDE Texture REPETITION in Unreal Engine - UE4 Tutorial」で説明されています。

そのためにはUE4からMega Scanの使用方法を勉強しなければなりません。

ここでします。

Bridgeをdownloadすれば良いみたいです。

適当に入力してたらDownload出来たみたいですが、このTutorialの説明、親切じゃないです。

調べたらMegascans to Unreal Engine 4 Workflow - How to install Bridge plugin in UE4にdownloadするための手順が一つ一つの説明されていました。こっちのやり方に沿ってやればよかったです。

以下の箇所のDefault Projectの部分に適当なFolderを指定したのですが大丈夫でしょうか?

f:id:kazuhironagai77:20210328232943p:plain

「Megascans to Unreal Engine 4 Workflow - How to install Bridge plugin in UE4」では何も指定していませんでした。

Projectを開いて見たらMega scansのTool buttonが出来ていました。

f:id:kazuhironagai77:20210328233016p:plain

よし、試しに何かBridgeからUE4に送ってみます。

兎に角、質の高いRockのTextureがほしい私は、Rockで検索して適当に選択していったら以下のAssetが出て来たのでこれをDownloadします。

f:id:kazuhironagai77:20210328233045p:plain

TutorialではBridgeの右側に設定を選択出来るDetailみたいなのが表示されていますが、私のにはありません。

f:id:kazuhironagai77:20210328233104p:plain

ないんですが、右上の矢印をクリックしたらDownload出来ました。そしてもう一回クリックしたExport出来ました。

UE4をみたらDownloadされています。

f:id:kazuhironagai77:20210328233123p:plain

出来たと思ったら、全部4kじゃないですか。

やっぱりBridgeのDetail画面をどうにかして表示して2kに設定しないと。

Assetをクリックして選択した状態になったら普通に表示されました。

f:id:kazuhironagai77:20210328233141p:plain

もう一回やります。

f:id:kazuhironagai77:20210328233157p:plain

今度は2kでImport出来ました。

一応Bridgeからassetを得る事が出来るようになったので、Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4に戻ります。

5.4 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:Landscapes

重要だと思った事をまとめておきます。

Section、Componentについての説明はありませんでした。しかしLandscape Technical Guide のリンクを紹介してそこで紹介されている設定から合っているのを選べば良い。と説明していました。

Landscapeにおいて特別な技法は紹介していませんでした。

山や谷を本物そっくりに作成する方法が紹介されるのかと期待したのですが、そういうのは無かったです。本物そっくりのLandscapeが作成したい時は、World machineやGaiaを使用して作成するそうです。「マテリアルデザイン入門」でもLandscapeはWorld machineを使用して作成したものをHeight mapにしてImportしたと書かれていました。

一寸だけ調べて見ます。

World machineで調べたら、以下のソフトが検索で出て来たのですが、

f:id:kazuhironagai77:20210328233233p:plain

似たような名前で、World Creatorと言うソフトもありました。

f:id:kazuhironagai77:20210328233256p:plain

World machineと言っているように聞こえるですが、ひょっとするとWorld Creatorと言っていたのかもしれませんね。

Gaiaも調べて見ます。

これの事かと思ったらこっちも

f:id:kazuhironagai77:20210328233316p:plain

Gaeaと言う似た名前のソフトがありました。

f:id:kazuhironagai77:20210328233336p:plain

LandscapeがUE4より簡単に作成出来かつ無料ならこっちのソフトの使用も考えてみます。

後で、検討しましょう。

Paintの設定の仕方は、先週勉強した「Landscape Essential Concepts」のPaintのやり方とほとんど同じでした。確認のために「マテリアルデザイン入門」も見ましたら、こっちでも同じやり方していました。

あんまりにもやり方が同じ過ぎて、ちょっと気持ち悪い位です。

5.5 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:Foliage

特にないです。

5.6 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:Blueprints

Tick関数を使用した時に、Delta secondで時間を調整していたのですが、私の作成中のゲーム、このやり方でやってなかったかもしれません。後で確認します。

初心者にはかなり難しい内容のような気がします。作れるんでしょうか?

5.7 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:Creating a Photorealistic World

のっけから、超重要な情報がありました。

f:id:kazuhironagai77:20210328233412p:plain

UE4であるfolderをMove toした後、前のFolderが残っているので消去しようとすると出来なかったり、「これこれのfileが残っています。本当に消していいんでしょうか?」と聞かれたりします。その時はこのFix Up Redirectors in Folderを選択するそうです。すると前のFolderに残っているfileが無くなって安全に消せるようになるそうです。

試してみました。

Imported Assets フォルダーを作成してその中にGood Skyを移動させました。

f:id:kazuhironagai77:20210328233430p:plain

残ったGood Skyのフォルダーを消そうとすると、消せません。

Contentを選択して、Fix Up Redirectors in Folderを選択します。

すると残ったGood Skyのフォルダーが消せました。

Landscape内をスムーズに移動するためには、Camera Speedの値を最大にすると良いみたいです。

f:id:kazuhironagai77:20210328233448p:plain

流石に一時間以上の作成は見ていられなくて途中で飛ばしてしまいました。

5.8 Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4を勉強して:まとめ

ハッキリ言って直せる所と直せない箇所がある事が分かりました。

  • Textureは、Mega Scanを使用する。->出来るようになった。
  • Photorealistic なLandscapeは別なソフトで作成する必要がある。->今日は無理。

しかしTutorialの内容は理解したので次の「How to HIDE Texture REPETITION in Unreal Engine - UE4 Tutorial」を勉強してタイルのようなTextureを直そうと思います。

5.9 How to HIDE Texture REPETITION in Unreal Engine - UE4 Tutorialを勉強して

もう一回、このTutorialを見ます。

<質の高いTextureを使用する。Mega ScanのTextureを使用する>

Mega Scanを使用出来るようにしました。

<Macro variationのあるtextureを使用する>

GoldのmaterialにMacro variationがあるみたいに言っていたので、開いてみたらありました。

f:id:kazuhironagai77:20210328233607p:plain

ありましたが、これで距離によってTextureが変わるのでしょうか?

良く分かりません。

<Distance blendを使用する>

やり方は大体理解出来ました。「マテリアルデザイン入門」に書かれている方法と同じに見えますが、作成した後でそれも検討します。

<Materialを変化させる>

Palinノイズを使用して地面と草を分けたりしています。

6.Landscapeの直し

それでは先週作成したLandscapeを直していきます。

Foliageは邪魔なので外します。

f:id:kazuhironagai77:20210328233707p:plain

6.1 Landscapeの直し

UE4のLandscapeではphotorealisticな地形を作成するのは限界があるのは分かりましたが、だからと言って以下のようなlandscapeで良い訳はないです。

f:id:kazuhironagai77:20210328233731p:plain

出来るだけ自然な形になるように直していきます。

f:id:kazuhironagai77:20210328233820p:plain

6.2 Mega Scanから Dirt MaterialをImport

soil_dirt_pjExP0をMega ScanからImportしました。

f:id:kazuhironagai77:20210328233841p:plain

Material Functionに変更して

f:id:kazuhironagai77:20210328233901p:plain

M_Landscapeに使用してみます。

f:id:kazuhironagai77:20210328233920p:plain

こんな感じになりました。

f:id:kazuhironagai77:20210328233936p:plain

近づいて見ると、タイルタイルしています。

f:id:kazuhironagai77:20210328233957p:plain

6.3 Macro variationのあるtextureを使用する

M_Metal_Goldから丸々コピーしました。

f:id:kazuhironagai77:20210328234032p:plain

近くを見ると、Textureがタイルタイルしているのは変わりませんが、遠くが斑模様になってちょっとだけリアルに見えます。

f:id:kazuhironagai77:20210328234051p:plain

以下にMacro variationを外した状態を示します。一目瞭然です。

f:id:kazuhironagai77:20210328234107p:plain

6.4 Distance blendを使用する

Distance blendを作成する前に、Textureの大きさを変えたら本当にタイルタイルしている状態が消えるのか試してみました。

0.25を掛けています。Textureは4倍の大きさになっているはずです。

f:id:kazuhironagai77:20210328234129p:plain

それでもタイルタイルしています。

f:id:kazuhironagai77:20210328234154p:plain

このTextureは駄目なヤツかもしれません。

別なTextureに替えました。

f:id:kazuhironagai77:20210328234219p:plain

既にタイルタイルしていません。

一番タイルタイルしている距離でも以下に示したようにほとんど分かりません。

f:id:kazuhironagai77:20210328234245p:plain

ゲームを始めてもTextureがタイルタイルしている所はないです。

f:id:kazuhironagai77:20210328234305p:plain

一応勉強と言う事で、Dirtの方だけ実装してみました。

f:id:kazuhironagai77:20210328234345p:plain

TutorialではDistance_Blendのパラメーターは単なる数字ですが、

f:id:kazuhironagai77:20210328234409p:plain

以下の様になっています。想像しているよりもかなり複雑な関数のようです。

f:id:kazuhironagai77:20210328234428p:plain

結果の違いは良く分かりませんが、

f:id:kazuhironagai77:20210328234446p:plain

敢えて結果の違いが可視化されている箇所を探すと

f:id:kazuhironagai77:20210328234507p:plain

数メートル下がるとイメージが以下の様に変化します。

f:id:kazuhironagai77:20210328234527p:plain

正し、Textureが良いので、イメージが変化しなくてもタイルタイルはしません。

作り方は分かりました。

6.5 Materialを変化させる

これ実際に作成してしまうと、折角塗った個所が上書きされてしますので、コードだけ真似て見ました。

f:id:kazuhironagai77:20210328234558p:plain

この状態でUVをTexCordから直接とるのは間違っている気がしますが、今回は形だけの作成なので深くは検討しません。

残念ながら時間が無くなってしまったので今週はここまでです。

7.まとめと感想

今週は以下の事をやりました。

  • DocumentLandscape関連の所を読みました。WaterFoliage Toolです。
  • Fog Effect、そしてHierarchical Level of Detailは、直接は関係なかったので今回は読まなかったです。
  • 日本語の資料は「マテリアルデザイン入門」を少しだけ読みました。
  • UIWSの使用方法も勉強しました。
  • LandScapeの直しとして「How to HIDE Texture REPETITION in Unreal Engine - UE4 Tutorial」と「Unreal Engine 4 Beginner Tutorial - Create Worlds in UE4」を勉強しました。
  • そこで勉強した知識を活用して先週作成したLandscapeを改善しました。

来週は

  • Landscapeの直しの続き(Tutorialの2と3も勉強する)
  • Foliageの改善(Cull Distanceの使用)
  • 水の追加
  • Projectに使用する実際のLandscapeの作成

などを行いたいと思います。

今週はかなり疲れました。

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

f:id:kazuhironagai77:20210321230424p:plain

<前文>

引用とネタバレ。もしくは批評と著作権

引用の英訳はCitationだと思います。何で和英辞典には引用の英訳としてQuotationが紹介されているんでしょうか?Quotation って‘’の事でしょう。論文の書き方でも引用について説明する時はCitationって書いてあります。

しかし心配なので調べて見たら、英語のCitationとQuotationの定義も結構曖昧でした。その中で以下に示した3つの意見が多かったです。

  1. 同じ
  2. イデアを引用するのがCitation。文章をそのまま引用するのがQuotation
  3. ‘‘の中の引用した文章がQuotation。どこから引用したのか説明した部分がCitation

因みに、文章内で引用元を説明したのがCitationで、文章の下に引用元を詳しく解説したものがReference(参照)と言う説明もありました。

これ論文だったら、その論文を発表する雑誌の編集方針に従う訳で、別な雑誌が別な基準を示していたとしても、基準を明確に示してくれさえすれば問題ないです。

同じ事が著作権についても言えるわけで、国によって著作権の考え方が違っても明確に基準さえ示してくれれば問題ないはずです。

私は著作権について漠然と理解したのはアメリカに住んでいた時だったので、多分にアメリカ人の考える著作権的な考えが自分の中で正しい著作権として存在しています。そしてその考え方は日本でも通用するとずっと思っていました。

所が最近、アメリカ人の友人から「日本の著作権にはFair useの概念がない。」と言われかなりビックリし、本当かどうか調べました。その過程で日本の著作権に対する考え方を理解し更にアメリカの著作権と比較する事で、結構著作権の本質的な部分に気が付きました。

勿論それは、私の主観ですので、法律的に正しい訳ではないかもしれませんが、一遍の真実を含んでいると思いますのでここに書き記しておきます。

アメリカ人の考える著作権とは>

まず、アメリカ人の考える著作権について説明します。

最初に断っておきますが、あくまで一般的と言う注釈付きです。ので絶対アメリカ人全員がこの考え方を持っているとは断言はしません。ただしキリスト教徒かつ、大卒レベルのアメリカ人、大学でしっかり勉強したアメリカ人なら絶対共有しているイメージだとは、私は思っています。

宇宙は神様が作りました。そこから地球や海とか動物、そして最期に自分に似せて人を作りました。

では、人が作成したモノの所有権は誰にあるのでしょう。

はい。人が作成したモノの元は全て神様が作成したので…。

神様のモノです。

これは幾つかバリエーションがあって、人が作成したものはその人から神様が具現化したと考える人もいます。しかし結論は一緒で、全てのモノの所有権は神様に属します。

この全てのモノは神様のモノと言う考え方はまあ、日本人である私でも、納得出来るのですが、教会が全部持っててしまうとなると、全然納得出来ません。

それとはまったく別に、これ神様が作った物を元にしては作れないよね。というモノがあります。例えば、地球が丸い事を発見した事です。その当時の教会は「地球は平らである。」と主張してたので、教会=神様である限りは、神様は地球が丸い事を発見する事は出来ません。

じゃ誰が発見したんだとなると、人が発見した事になります。

ここでアメリカ人は、人は神様に似せて作られたので、神様しか出来ない新しいモノを作成する事は可能なのだ。とかなり宗教的な納得をしますが、当時の私もそんな理解をしました。(ただし、この人の中にアジア人が入っているかどうか、かなりの数の白人は、この場合の人の定義に、白人しかも一部の白人しか入れていない気がします。)

では、その人が作成したモノの所有権は誰に属するのでしょうか?

勿論、その作った人です。

その所有権はどこまであるのか?

神様が作った物は何処まで進んでも神様のものである様に、人の作った物も何処まで進んでもその人の物であるはずです。

それを法律として明確化したものが著作権です。

だから著作権は元々、神様の持つ権利と同等の強さを持つとんでもない権利なんです。

そしてこの地上でその神様の持つ権利を管理するのが教会であるように、人の作った物の権利を管理するのは大学なんですが、著作権に代表される人の権利を、旧約聖書に出て来る神様のように行使したら、研究が全く出来ない。なので権利はあるのだけども実行出来る部分に制限を付ける事にしました。その制限の基準がFair useな訳です。

そしてこのFair useの本当の意味は「常識の範囲で自由に運用してね。」と言う事です。

そしてこのFair useの中で非常に大きなウェイトを示すのが引用なんです。

だから日本ではFair useの概念がないと言うと「えっ」なるんです。

<日本の著作権への考え方>

自分で調べた限りの感想ですが、日本の著作権にFair useの概念がないというのは全くの誤解です。Fair useと言う曖昧な概念をそのまま導入すると、何はOKで、何が駄目なのか分からないので、具体的に著作権の例外事項を定めているだけです。その証拠に引用は著作権の例外として認められています。

明治時代に西洋の文明の本質を輸入し接ぎ木したのが日本の近代化なので、例え日本にキリスト教的な神様の所有物と言う概念が無くても日本の著作権は、暗黙的にですが、人の製作物に対して神の製作物と同等の権利を認めています。のでFair useの概念が本当になかったら実際の運用が全く出来ないです。

正直笑ってしまったのが「大学受験における入試問題に使用される文章は著作権の行使が出来ない。」と定めている文章でした。

アメリカと言うか、西洋的な考えに立つと、人の作った物の権利を管理するのは大学なので、大学こそが著作権をどの程度守るのかを決める訳です。法律はそれを文章化して、違反に対しての罰則を規定する事しかできません。上の文章はまさしくそれを体現しています。日本の話ですが。

これは日本における著作権の本質は、アメリカを代表とする西洋と全く変わらない事の証明でしょう。

はい。

私の結論としては日本の著作権の考え方、実行の仕方に他の西洋諸国との本質的な違いはない。と言う事です。

<引用とは何ですか?>

はい。ここで引用とは何ぞや。という事に対して私の考えを述べます。私の考えそのものはかなりアメリカの著作権の考え方に負っていますが、今までの議論から日本の著作権にもほぼそのまま当てはまると考えられます。

引用とは「○○さんはこう言っているけど。それって違うよね。」の○○さんの言っている内容が、引用に当たります。

ここで大切なのは、それって違うよねの後が、主体になっていないといけない事です。これから何故○○さんの言っている事が間違っているのか、そして何が正しいと考えるのかについて説明しなければ引用になりません。

所謂、転載やplagiarismは「○○さんの言っている事」の紹介が主体になり、自分の意見はありません。

<引用とネタバレ。もしくは批評と著作権

でも、それだと、自分の主張を言う為なら、ネタバレしても良いって事になりませんか?

もしくは勝手に引用されてボロクソに批判されても黙っていないといけないって事でしょうか?

との疑問が出て来ます。

それで最初のFair useの概念に戻る訳です。常識に基づいて判断してと。

自分が使用する側の時は、使用される側の立場に立って考えてねとか、今までの慣習ではどうなっているのか調べて見てね?とかそう言う事です。

 

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

<本文>

1.今週の予定

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

  • Level デザイン
  • Widget内のBPの整理
  • Effectの勉強と作成

2.Levelデザイン: Tutorialで勉強する

2.1 使えるTutorialを探す

Level Designの超基本はこれまでの勉強で理解しました。しかしもっと勉強すべき事はあります。色々なTutorial を見て参考になる優秀なものを見つけましょう。

判断の基準として以下の事を念頭に置いておきたいと思います。

  • 川のデザインが正しい。
  • 水のMaterialに最新のモノを使用しているか、使用しない場合は理由を明確に述べている。
  • Component EdgeSection Edgeそして Individual Quadの正しい解説をしている。

まず川のデザインですが、はるか昔に勉強したLevel designで川と言うのは、以下のイラストの様に上流が分岐していて下流に行く程、一本に成るらしいです。

f:id:kazuhironagai77:20210321230713p:plain

決して以下の絵のように上流が一本で下流に行く程、沢山の支流が現れる事はないそうです。

f:id:kazuhironagai77:20210321230728p:plain

所が、Level Designの初心者はかなりの確率で上流が一本で下流に行く程、沢山の支流が現れる川を作ってしまうらしいです。

まあ、ゲームなんで科学的に正しい地形をデザインしなければならない訳ではないですが、現実の地形に対してこの程度の注意も向けられない人が作ったtutorialは、大きな欠陥がある可能性が高いので使えるTutorialには該当しないでしょう。

次に水のMaterialですが、4.26 からはWater Simulationが付いていますし、それ以前のversionでは

f:id:kazuhironagai77:20210321230745p:plain

が使用出来るからです。

Unityではなく敢えてUE4を選択する人達の理由の一つが、その最新のグラフィックにあります。その利点が教えられないUE4のデザイン系のTutorialは価値がないです。

最後に、先週勉強したComponent Edge、Section Edgeそして Individual Quadの正しい解説がされていないTutorialも質が低いと思われるので避けます。

まず公式のOnline learningからは以下の教材を見てみようと思います。

f:id:kazuhironagai77:20210321230802p:plain

f:id:kazuhironagai77:20210321230811p:plain

f:id:kazuhironagai77:20210321230819p:plain

CourseとLearning Pathはどう違うんでしょうか?

調べたけど解説は見つからないですね。

YouTubeにはUE4のLevel DesignのTutorialをまとめた人がいました。

f:id:kazuhironagai77:20210321230840p:plain

この一番最初に紹介されているUE4: Good-Looking Randomization for Procedural Buildingsを作成したTech Art AidはMeshではなくInstanceを使用する事でLevel上のサイズをとても小さく出来る事を教えてくれた貴重なTutorialです。この選択は結構期待して良いかもしれません。ここに載っている Tutorialもチェックしてみましょう。

そう言えば、「マテリアルデザイン入門」にInstanceを使用する話が普通に解説されていて何かガックリした事を思い出しました。この本も今回、読み直しましょう。

Learningの一番左にLevel design Quick Startがあります。

f:id:kazuhironagai77:20210321230855p:plain

念のため調べて見たら、いつものヤツでした。

f:id:kazuhironagai77:20210321230912p:plain

流石にこのレベルのヤツは全部理解していると信じたい。今回はこいつはスキップします。

更に、UE4公式のDocumentationでは、

f:id:kazuhironagai77:20210321230930p:plain

Water、Foliage Tool、Fog Effect、そしてHierarchical Level of Detailのような私が見たいものズバリの内容がありました。

これらのTutorialはかなり良さそうです。

f:id:kazuhironagai77:20210321231137p:plain

全然関係ないですが、hierarchyの発音はカタカナで書くと「ハイ、ラ~キィ」で決して「ヒエラルキー」ではないです。

2.2 Tutorialの候補を絞る。

絶対やりたいのはDocumentのWater、Foliage Tool、Fog Effect、そしてHierarchical Level of Detailですが、なんせ文章なんでビデオで見るよりかなり面倒です。さらに読書は他の学習方法より効果が薄いらしいので最後に回します。同じ理由で「マテリアルデザイン入門」の読書も最後に回します。

となるとやっぱり最初にチェックするのは以下に示した公式のOnline learning の3つですかね。

f:id:kazuhironagai77:20210321231202p:plain

2.3 UE4公式のOnline Learning感想

2.3.1 World Building Kickstart

Sjoerd de Jong氏のTutorialでした。

彼のTutorialはLevel designに限らずどのTutorialも見て損はないです。前に彼が作ったMaterialのTutorialを見て大変勉強になったのを覚えています。

今回は全体像を把握するためにTutorialの半分位まで見ました。Level designに使用する機能を全部簡潔に説明しています。ただこれだけ見たのでは、実際に使用出来るまでには成れなさそうです。UE4には、こんな機能があるのかと言う情報源として使用するのが最適かもしれません。

後、彼もhierarchyを「ヒエラルキー」って発音していたんですが。前にインド人の先生でhierarchyを「ヒエラルキー」って発音する人が居て、hierarchyを「ヒエラルキー」って読むのは日本人だけじゃなかった。と思った事があったんですが。

ひょっとしてイギリス英語だとhierarchyを「ヒエラルキー」と発音するの?と調べたんですが、少なくとも私が調べた範囲では、イギリス英語でも「ハイ、ラ~キィ」と発音していました。

ドイツ語?と思ってそれも調べましたが、何か全然違う発音でした。

アメリカでcomputer scienceの勉強をしたら()、{}、そして[]の読み方を知らないって事はないので、アメリカ出身じゃない事だけは確かですが、彼、何処出身なんでしょうか?

2.3.2 Becoming an Environment Artist in Unreal

最初のイントロ部分だけ見たんですが、Landscapeの作り方についての解説は無いみたいです。

良く考えて見れば、Environmentの作成はLandscapeの作成だけじゃなくて、Lightingの設定やMaterialの作成もある訳でそっちが主体なのかもしれません。というかLevel designer = Environmental artist と勝手に思っていましたが違うのかもしれません。

そう言えば「Unreal Engine 4で極めるゲーム開発」にゲーム開発に関わる専門職の説明が載っていました。

見てみるとLevel designerはEnvironmental artistが作った建物なんかをLevel上に配置するのが仕事みたいです。つまり二つは別な職種みたいです。

このゲーム開発に関わる専門職ってあくまでも「Unreal Engine 4で極めるゲーム開発」における定義だと思っていたんですが、違うみたいですね。

ここでちょっとUE4の教育システムに対して苦言を言います。

この分類がUE4を使用したゲーム開発全般に通じる職種なのか、それとももっと大きくゲーム産業全体でこのような職種分けが行われているのか知りませんが、少なくともProgrammerである人がUE4の勉強をしたいと言ったら、この職種の中のEngineer になるための勉強をしたいと言う意味になるはずです。しかし私が今までUE4で見たProgrammer向けの教材のほとんどはBPの代わりにC++をScript languageとして使用するだけのもので、とてもこの職種で言うEngineerに当たる役割が果たせるように成れるとは思えません。

ゲーム産業全体でこのような職種分けが元々存在しているのなら、ゲーム産業内でEngineer としてやって行きたいprogrammer向けにこんな教育しか提供してこなかったUE4の教育システムはちょっと問題だと思います。

ゲーム制作ってProgrammerの分野でも花形ですのでGoogleAmazonでProgrammerやっているレベルの人でもちょっとゲーム作ってみたいと思う人はいっぱいいるはずです。そういう人たちがUE4のProgrammer向けの教材見て「俺ら向けの教材じゃないね。Unityでゲーム作ろう。」となっていたとしたら悲しいです。

今は、Online learningがあるのでProgrammer向けの教育も内容のレベルが上がっているのかもしれませんが、一寸文句を言わせて頂きました。

2.3.3 Constructing Believable Environment

これもEnvironmental artist用の教材ですね。ざっと目次を見ましたが、ほとんどLightingについての話です。Environmental artistは別名、Lighting artistとも呼ばれるらしいので、これはこれで納得です。

2.4 UE4公式のOnline LearningにあるLandscapeを勉強するための教材

がありました。こっちを勉強すべきでした。

f:id:kazuhironagai77:20210321231322p:plain

イントロ部分を見た所は、Landscapeの基本についての解説のようです。

軽くですが全部見てみます。

2.4.1 Accessing Project Files Using Marketplace Redemption Codes

Redeemして提供されているsampleからProjectを作成しようとしたら、見つかりません。

散々探しても見つからないのでlauncherの方からRedemption Codeを入力したら、あなたは既にこのprojectを持っています。と返答されました。

もう一回vaultを確認したらありました。

f:id:kazuhironagai77:20210321231357p:plain

ずっとTerrain‗ECで探していました。

2.4.2 Importing Terrain from a File

Landscapeの元をHeight map Fileから作成する方法が説明されています。

f:id:kazuhironagai77:20210321231419p:plain

これが知りたかった。

前にUEC++の勉強でPerlin Noise からLandscapeを作成ました。やり方は完全に忘れてしまいましたが、その過程でイメージをlandscapeとしてimport出来る事は何となく覚えていました。

このやり方が分かれば自作した地図からLandscapeが作成出来ます。

f:id:kazuhironagai77:20210321231435p:plain

あれ、提供されたProjectにはHeightmap用のPNGがないですね。

4.25だからかもと思って4.24で作り直しましたがやっぱりないです。

まあいいです。残りは自分で調べます。

2.4.3 Creating a New Terrain

Section のサイズ、Section / ComponentそしてComponentの数を決定しました。

f:id:kazuhironagai77:20210321231457p:plain

しましたが、これらのパラメーターが何を示しているのかについての説明が全くありません。

減点1ですね。

先週、まとめた内容をもう一度ここに記しておきます。

まず、Landscapeに置いて最初単位は1m^2です。固定されています。パラメーターをどう弄ってもこれは変わりません。

次の最小単位であるSection内にこの最小単位である1m^2の面が何個入るのかを決定するのがSection Sizeです。今回は63x63個入るようにします。入る1m^2の面の数が多くなればなるほどsectionのサイズが大きくなります。だからSection Sizeと名付けています。

次の単位はComponentです。基本的にSectionとComponentは1:1の関係ですが、一つのComponentに2x2、計4つのSectionを入れる事も出来ます。

最後にComponentの数ですが、今回は2x2で4つとしました。UE4はComponentの数は1024以下にする事を進めています。

63*2*2 = 254で1を引くとOverall Resolutionの253になります。

Componentは rendering, visibility calculation, そして collision を担当しています。

あれ?

一つのComponentが一つのHeight Map用のText を保持しているから一つのComponent内のSectionの数が増えると、計算は楽になる代わりに雑な作りになるはずでしたがrendering, visibility calculation, そして collisionもComponentで担当していると全部の計算が楽になりますね。

ちょっと確認してみます。

Landscape Technical Guideによると、Componentは、Componentは rendering, visibility calculation, collision の計算をして、更に一つのComponentが一つのHeight Map用のTextを保持しているそうです。つまり先週の説明は合っています。

Sectionは大前提としてLandscape LODの計算をするための最小単位だそうです。それでSection の数を増やす事で、Componentの数が減ればパフォーマンスは向上すると書かれていました。まあそうですね。rendering, visibility calculation, そして collisionも含めて全部の計算が楽になるわけですね。

2.4.4 Understanding Components

はい。ここでしっかりComponentについて説明されていました。

Componentがrendering, visibility calculation, collisionを担当する事、一つのComponentが一つのHeight Map用のTextを保持する事、Sectionを増やす事でComponentの数を減らしてその結果、Performanceが向上する事など全部説明されていました。

2.4.5 Managing our Landscape

LandscapeのManageのSection toolのSelection, Add, Delete, Move to LevelそしてChange Component Sizeについての解説です。

f:id:kazuhironagai77:20210321231535p:plain

Selectです。

Componentを選択します。

f:id:kazuhironagai77:20210321231551p:plain

Addです。

Componentを追加します。追加出来る箇所はComponentと隣り合っている箇所のみです。

f:id:kazuhironagai77:20210321231607p:plain

Deleteです。

選択したComponentを消去します。先程Addで作成したComponentを消去しました。

f:id:kazuhironagai77:20210321231622p:plain

Move to Levelです。

f:id:kazuhironagai77:20210321231651p:plain

と説明されています。動画でも同様の説明がありました。ありましたが、この意味が分かりません。

Change Component Sizeです。

Componentの設定を変更します。

f:id:kazuhironagai77:20210321231706p:plain

これって全部のComponentの設定を変えるのでしょうか?それとも一個だけ変える事も可能なんでしょうか?

こんな機能知らなかったです。

大変勉強になりました。

2.4.6 Quiz 1

満点でした。

流石にArtiest向けなのでクイズは簡単に作られています。

2.4.7 Brush Settings and Viewport Feedback

Sculpt Toolの使用方法についての解説でした。

f:id:kazuhironagai77:20210321231732p:plain

このcircleのサイズが

f:id:kazuhironagai77:20210321231748p:plain

以下の二つのParameterでコントロールされている事についての解説でした。

f:id:kazuhironagai77:20210321231801p:plain

流石にこれは知っています。

2.4.8 The Most Common Landscape Brushes

ここでは実際にブラシを使用してLandscapeの形を変形させました。

f:id:kazuhironagai77:20210321231822p:plain

Shiftを押すと逆になるのはすっかり忘れていました。

2.4.9 Using Advanced Forms of Sculpting

更なるツールの使い方の説明でした。

2.4.10 Utilizing the Region Tools

Selectionの使用方法についての説明でした。

f:id:kazuhironagai77:20210321231850p:plain

イラストを描くときに使用する選択のLandscape版ですね。

こういう機能はいっぺんに教わっても忘れてしまいます。使いながら覚えるのが一番良いですが、何せLandscapeの作成を趣味にする訳にもいかないので覚えるしかないですね。

2.4.11 Quiz 2

また満点でした。

テスト至上主義の弊害ですね。何もToolを使える様に成っていないのにテストだけ見ると理解したかのようになっています。

2.4.12 Understanding Material Layers

流石にもう飽きて来ました。

Landscapeがしょぼくて炎上したゲームでも紹介してこの機能を使えばそのLandscapeでもこんなに綺麗に仕上がります。みたいな紹介されないと正直、勉強する気になれないです。

数えたら後、10個もLectureがあります。

あー、きついです。

ここからのTutorialではLandscapeに色付けしていくようです。

更にInstructorがここでハッキリ忠告しています。「ここで習う程度の技術では、本物そっくりのLandscapeを作成する事は出来ないと。しかしそのために使用するToolの使い方を理解する事は出来ます。」と。

Material functionについての説明でした。

もう分かりました。

Landscapeを30個位、自分で制作しないとこれ以上の勉強は机上の空論に成ってしまいます。一端ここで区切りましょう。

2.4.13 ここまでのまとめ

まず、Landscapeに関して使えるTutorialを見つけると言う目的に対しての結論ですが、公式のOnline learning にある「World Building Kickstart」で十分と考えられます。

更にこのTutorialで基本を身に付けたら、公式のDocumentにあるWater、Foliage Tool、Fog Effect、そしてHierarchical Level of Detailを勉強すべきでしょう。その上でWater Simulationか、UIWSで水の製作の仕方を勉強すると良いと思います。

Landscapeの作成には地形を色付けする必要があり、その工程ではMaterialの作成が必要になります。「World Building Kickstart」ではQuiz 2 の後のLectureで解説しています。この部分を勉強する時は「マテリアルデザイン入門」も読み直しておくべきでしょう。

後、Environment artの勉強もする必要があります。これはLandscapeとは別の分野ですが、密接に関係しています。

2.5 兎に角Landscapeを作成

今まで学んだ事を使用してLandscapeを作ってみます。

出来ました。

f:id:kazuhironagai77:20210321231932p:plain

  • ManageのAdd やdeleteを使ってComponentを減らしたり増やしたりしました。
  • Selectionでマスクして一定の場所にだけFlatしたりしました。
  • Change Component sizeを使用してComponent のパラメーターを変更したりしました。
  • Erosion, hydro erosion, noiseも使用してみました。
  • Rampで坂を作りました。

ゲーム内の風景は以下の様に成っています。

f:id:kazuhironagai77:20210321231958p:plain

正直、これでも良いんじゃね。と言う気分です。

HeightmapとしてExportしてみました。

以下のボタンを右クリックでExport出来ます。

f:id:kazuhironagai77:20210321232011p:plain

正し、この単純な方法を見つけるのに結構時間かかりました。

何かUE4のdesignerの中には結構意地悪な回答して質問者を煙に巻いている人がいますね。

気を付けましょう!

Exportしたイメージはこんな感じです。

f:id:kazuhironagai77:20210321232027p:plain

白い方が高いみたいですね。

地面にあたる部分でも結構灰色ですね。

サイズは509x382 pixelでLandscapeのResolutionと同じでした。

f:id:kazuhironagai77:20210321232042p:plain

2.6 ゲーム内に作成する予定のLandscapeと同じサイズのLandscapeを作成

実際に作成する時と同じ条件でLandscapeを作成してみます。

f:id:kazuhironagai77:20210321232105p:plain

こんな状態です。

f:id:kazuhironagai77:20210321232119p:plain

この状態でHeightmapでExportしてみます。

Medi bangで開いて見るとまっさらのheightmapの色は128に成っていました。

f:id:kazuhironagai77:20210321232137p:plain

つまり、真ん中ですね。

そこに作成する島の絵を重ねます。

f:id:kazuhironagai77:20210321232153p:plain

以下の様になりました。

f:id:kazuhironagai77:20210321232209p:plain

試しにこれをheight mapとしてimportしてみます。

f:id:kazuhironagai77:20210321232232p:plain

一応出来ました。

微調整していたら川が無くなってしまいました。

f:id:kazuhironagai77:20210321232249p:plain

失敗です。

今度は以下の様に島と川だけのheight mapにしました。

これを加工します。

f:id:kazuhironagai77:20210321232303p:plain

これでも島とそれ以外の部分の差があり過ぎました。

f:id:kazuhironagai77:20210321232324p:plain

もう一回作り直します。

f:id:kazuhironagai77:20210321232342p:plain

今度は川の段差もほとんどありません。

f:id:kazuhironagai77:20210321232359p:plain

Landscapeの形状はこれでいいです。Level designerになる訳ではないのでこの位で十分です。

2.7 Tutorialの続き

先程のtutorialの続きをやります。残り10個なので頑張って終わらせます。

2.7.1 Painting Tools

凄い。下のscreen shotを見て下さい。 本物そっくりです。

f:id:kazuhironagai77:20210321232427p:plain

しかしどうしてコレが作成出来たのかが全く分かりません。

取りあえず手順を以下にまとめます。

最初にLandscapeを選択してLandscape Materialに付属のmaterial Landsape_Materialを選択します。

f:id:kazuhironagai77:20210321232454p:plain

するとLandscapeのPaintのTarget Layers内にGrassとRockが表示されます。

f:id:kazuhironagai77:20210321232514p:plain

f:id:kazuhironagai77:20210321232523p:plain

Grassの+を押すとWeight-Blend Layer(normal)とNon Weight-Blended Layerが表示されるのでWeight-Blend Layer(normal)を選択します。

f:id:kazuhironagai77:20210321232539p:plain

するとlandscapeがGrass一色になります。

次にRockの+を押して同様にWeight-Blend Layer(normal)を選択し、以下の設定に値を変えて

f:id:kazuhironagai77:20210321232557p:plain

ブラシでLandscapeをこすると、こすった所が、岩が草からむき出しになる絵が追加されます。

f:id:kazuhironagai77:20210321232613p:plain

うーん。良く分からん。

Landsape_Materialを開いたら以下の様に成っていました。

f:id:kazuhironagai77:20210321232628p:plain

成程、ここでMFunction_GrassとMFunction_Rocksがパスされている訳ですね。

2.7.2 Painting the Terrain

「2.7.1 Painting Tools」の続きです。それだけでした。

2.7.3 Foliage Edit Mode

Foliage の追加の仕方についての解説でした。

やり方を簡単にまとめるとFoliageを選択します。

f:id:kazuhironagai77:20210321232653p:plain

Add Foliage Typeに指定のmeshを追加します。

f:id:kazuhironagai77:20210321232709p:plain

現れたアイコンをクリックするとそのMeshの詳細が表示されます。

f:id:kazuhironagai77:20210321232727p:plain

これだけです。

この方法って実際のMeshじゃなくてInstanceを使用するんじゃなかったんでしたっけ。

うーん。良く分かりません。

2.7.4 Painting with Meshes

以下に示したFoilageのtoolの使用方法を説明しています。

まずPaintです。

f:id:kazuhironagai77:20210321232748p:plain

指定されたMeshをPaintします。

f:id:kazuhironagai77:20210321232805p:plain

Selectです。

f:id:kazuhironagai77:20210321232822p:plain

PaintされたMeshから一個だけ選択します。

f:id:kazuhironagai77:20210321232840p:plain

Lasso Selectです。

f:id:kazuhironagai77:20210321232855p:plain

円の中のMeshを全て選択します。

f:id:kazuhironagai77:20210321232914p:plain

Paint Bucketです。

f:id:kazuhironagai77:20210321232928p:plain

一括でLandscape全体にMeshを追加出来るとの説明でしたが、やり方が分かりません。

2.7.5 Using the Grass Tool

Material エディター内でGrass ノードをどのように使用するかについての説明と、そのGrass ノードを使う事によって自動で草のmeshを地形に追加する方法を説明します。

以下に草のメッシュを追加した後のscreen shotを示します。

f:id:kazuhironagai77:20210321232949p:plain

やり方を簡単に説明します。

FoliageからLandscape Grass Typeを選択します。

f:id:kazuhironagai77:20210321233005p:plain

Grass_2と名付けます。

f:id:kazuhironagai77:20210321233020p:plain

Grass Varietiesにgrassを追加します。

f:id:kazuhironagai77:20210321233035p:plain

以下の様にパラメーターを調節します。

f:id:kazuhironagai77:20210321233051p:plain

Landscape_Materialを開き

f:id:kazuhironagai77:20210321233105p:plain

LandscapeGrassOutputを追加します。

f:id:kazuhironagai77:20210321233120p:plain

f:id:kazuhironagai77:20210321233127p:plain

LandscapeGrassOutputのGrass Typesに先程作成したGrass_2 を追加します。

f:id:kazuhironagai77:20210321233148p:plain

次にLandscapeLayerSampleノードを追加します。

f:id:kazuhironagai77:20210321233204p:plain

f:id:kazuhironagai77:20210321233210p:plain

LandscapeLayerSampleノードのパラメーターを以下の様にセットします。

f:id:kazuhironagai77:20210321233228p:plain

以下に示した様にLandscapeLayerSampleノードとLandscapeGrassOutputノードを繋げます。

f:id:kazuhironagai77:20210321233244p:plain

以上です。

このやり方は今まで見た事ないかもしれません。単に忘れているだけかもしれませんが。

2.7.5 Debugging Painted Layers

現在、2つのLayerを使用しています。

f:id:kazuhironagai77:20210321233307p:plain

しかし、どちらがどの程度Landscapeに使用されているのかを区別するのは大変難しいです。

これを以下の様に表示しる方法を説明しています。

f:id:kazuhironagai77:20210321233324p:plain

やり方は、LitからVisualizersを選択してそこからLayer Debugを選択します。

f:id:kazuhironagai77:20210321233341p:plain

ModesからLandscape、Paintを選択し

f:id:kazuhironagai77:20210321233410p:plain

Target LayersのLayersにあるそれぞれのMaterialのRやGにチェックを入れます。

f:id:kazuhironagai77:20210321233428p:plain

これで上記のようにlayer毎に色分けされたlandscapeを見る事が出来ます。

2.7.6 Landscape Size Guide

Landscape Technical Guideを絶対読んでおけよ。と言うかなり素晴らしいアドバイスでした。

2.7.7 Controlling Collisions

ActorとlandscapeのCollisionを正確にすればするだけMemoryの負担は増えます。

その調整をするのがLandscapeのDetailにあるCollision内のCollision Mip LevelとSimple Collision Mip Levelです。

f:id:kazuhironagai77:20210321233454p:plain

0に近い程、正確に計算します。そしてMemoryの消費も上がります。

2.7.8 Landscape Essential Concepts Next Steps

特に記録に残す内容はないです。

2.7.9 Quiz 3

2問も間違えてしまった。

Grass Toolが、BPを使用する方じゃない方だと思って即答して間違えたのが一つで、これはケアレスミスみたいなもんです。

Collision Mip Levelが何をコントロールしているのかの質問の解答ってLecture中に説明あったんでしょうか?

全く記憶に無かったです。

全然分からなかったです。

一応、全部のLectureを見終えました。

これでPaintのやり方もFoliageのやり方も大体分かりました。

達成感が凄いですが、全体を見ると全然進捗していませんね。

2.8 Paintしてみる

早速、教わったやり方でPaintしてみます。

MyPaint folderを作成して

f:id:kazuhironagai77:20210321233530p:plain

M_Ground_GrassとM_Rockをコピーしました。

f:id:kazuhironagai77:20210321233546p:plain

この二つをFunctionに変更するのですがやり方を忘れました。

調べます。

Material functionの作り方そのものを教えているサイトばかり引っかかって、MaterialをMaterial Functionに変更する方法を教えてるサイトは見つかりませんでした。

仕方ない。

Landscape essential concept内のMaterial Functionを開いてどう作っているのかを確認します。

Make Material Attributesノードを使用していました。

f:id:kazuhironagai77:20210321233602p:plain

これが知りたかった。

MF_Ground_Grassを作成しM_Ground_GrassのBPを丸コピーしてMake Material Attributesノードに繋げます。

f:id:kazuhironagai77:20210321233618p:plain

MF_Rockも同様にします。

f:id:kazuhironagai77:20210321233633p:plain

次にMaterial、landscapeを作成します。

早速、問題にぶち当たりました。二つのMaterial functionをblendしよう、Layer Blendを探したら沢山の種類がありどれを選べばよいのか分かりません。

f:id:kazuhironagai77:20210321233650p:plain

調べたら、Layer Blend ノードの正式名称はLandscape Layer Blend ノードでした。

ふう。一安心と思ったらInputがないです。

f:id:kazuhironagai77:20210321233705p:plain

終わった。

このノードも違うのか。と思ったらLayersに追加する事でInputを作成出来るみたいです。

f:id:kazuhironagai77:20210321233720p:plain

f:id:kazuhironagai77:20210321233726p:plain

開いて見ると、色々なパラメーターを指定しないといけないみたいですね。

f:id:kazuhironagai77:20210321233746p:plain

これらのパラメーターの正しい値は何となく想像も付きますが、一応Landscape essential conceptで確認してみましょう。

f:id:kazuhironagai77:20210321233805p:plain

Layerの名前は何でも良いのでinputに接続するMaterial Functionと同じ様な名前にすると思われます。やっぱりGrassやRockを指定していました。

BlendTypeはLectureでTarget LayerでこのLayerを指定する時にWeight Blendを選択していたので、

f:id:kazuhironagai77:20210321233822p:plain

勝手にWeight Blendである可能性が高いと思っていましたらやっぱりその通りでした。

Preview Weightは、LectureでこのMaterialをLayerとして使用したら全部GrassだったのでGrassが1でRockが0に何処かで指定しているはずと思っていました。それがここだった訳です。

Landscape essential conceptで使用された値と全く同じにします。

f:id:kazuhironagai77:20210321233839p:plain

Landscape essential conceptではAmbient Occlusion は接続していないんですが、MF_Rockでは使用しているんですが。

分からないですが一応繋げておきます。

f:id:kazuhironagai77:20210321233902p:plain

やっとM_Landscapeが完成しました。

「2.7.1 Painting Tools」の解説の通りですが、Landscapeを選択してLandscape MaterialにM_Landscapeを指定します。

f:id:kazuhironagai77:20210321233918p:plain

するとTarget LayerにGrassとRockが現れるので

f:id:kazuhironagai77:20210321233937p:plain

Grassの+を押してWeight…を選択します。

するとLandscapeが緑一色になりました。

f:id:kazuhironagai77:20210321233952p:plain

今度は、Rockの+を押して同様にセットします。

ブラシの設定は適当にして、岩をpaintしてみます。

出来ていますが、これじゃ駄目ですね。

f:id:kazuhironagai77:20210321234009p:plain

拡大してみると分かりますが、Rockに使用しているMaterialがちょっと想像と違っていました。

f:id:kazuhironagai77:20210321234032p:plain

色を変えて、かなり弱めにPaintしてみましたがTextureのパターンが目立って違和感が凄いです。

f:id:kazuhironagai77:20210321234053p:plain

Lectureで習った事は出来るようになったのは確かなので、この問題は来週、検討します。

2.9 Grass Toolを使用してみる。

最後にGrass Toolを使って草を生やしてみましょう。Quiz 3でも間違えてしまった所なので慎重にやっていきます。

手順は「2.7.5 Using the Grass Tool」に書かれている通りなのでParameterのみ記していきます。

f:id:kazuhironagai77:20210321234115p:plain

草のStatic meshはいっぱいあったので適当に一個選びました。

M_Landscapeに以下のコードを追加しました。

f:id:kazuhironagai77:20210321234133p:plain

想像してたのより10倍位やばい状態になっています。

f:id:kazuhironagai77:20210321234155p:plain

草の種類を変えます。

更にGrass Densityも思いっきり下げました。

f:id:kazuhironagai77:20210321234213p:plain

結果です。

f:id:kazuhironagai77:20210321234233p:plain

f:id:kazuhironagai77:20210321234242p:plain

PCが凄い音だして計算してました。

一応、自分でも使える事は確認出来きました。

残念ながら時間が無くなってしまったので今週はここで終了します。

3.Widget内のBPの整理

来週にまわします。

4.Effectの勉強と作成

来週にまわします。

5.まとめと感想

今週はLevel design、WidgetのBPの整理、そしてEffectの勉強をやる予定でしたが、Level designの復習で終わってしまいました。

Level designはまず優れたTutorialを探す事から始めました。公式のOnline learningにある

f:id:kazuhironagai77:20210321234321p:plain

はかなり良いTutorialと思います。

後、Landscapeを作成するLevel designerとEnvironmental artistは違う職種のようです。Environmental artistはLevel designerが配置する個々の部品を作成する人で、Lightingの専門家みたいです。

Landscape Essential Conceptsで勉強して、Landscapeの作成方法、Paintの使用方法、Grass toolを使用したFoliageの作成方法などは一応出来るようになりました。

来週の予定は、

  • DocumentのWater、Foliage Tool、Fog Effect、そしてHierarchical Level of Detailを読みます。
  • 日本語の資料で関係している箇所もチェックします。
  • UIWSの使用方法も勉強します。

f:id:kazuhironagai77:20210321234350p:plain

  • Paintの見た目がオカシイ所を直します。(出来ればlayerをもっと増やしたいです。)
  • Grass toolで2種類以上の草を生やします。(見た目の違和感も無くしたい。)
  • Map1のLandscapeを完成させます。

以上です。

WidgetのBPの整理、そしてEffectの勉強は時間があったらやります。

 

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する  マップの作製など

f:id:kazuhironagai77:20210315000253p:plain

<前文>

英語発音まとめ

このブログに記載しているプロジェクトとは別に、日本人に区別が出来にくい英語の音素をminimal pairを使用して練習する事で区別が出来るようになる学習ゲームも作成しています。

そのソフトを作成するためかなり英語の発音について勉強しました。

その勉強成果をここにまとめておきます。

ただし最初に断っておきますが、私は10年以上アメリカで暮らしていましたが、言語学は全く勉強した事はありません。のでここから書く事は全くの独学です。専門家の人から見れば常識な事が書かれていたり、間違っている事もあるかもしれません。しかし私にとってはこれが正しいと思われる内容になります。

  • minimal pairで練習してもあるタイプのL とRの区別は限定的にしか出来な

のっけから否定的ですがminimal pairを使用する学習方法もSilver bulletではないと言う事です。非常に効果の高い学習方法ですが常識の範囲で使用する必要があります。

この区別が付かないタイプのLとRの場合も二つの単語の音を交互に聞いて、テストするとある程度の練習を積めば誰でも正解を選べます。しかし時間を置いてテストすると全く分からなくなります。

これは日本人が分からない音のもう一つの代表であるThと全く違う結果です。

ThはSやSHとminimal pairを使用して音の違いを学習すると大人でも完璧に分かるようになります。そして一端分かるようになると、自転車の乗り方を覚えたら生涯忘れないのと同じようにThの音そのものをずっと覚えています。他の日本人が英語をしゃべっている(通訳とか)のを聞いて「この人、THをチの音で代用しているわ。」とか「英語下手と思ったけどTHの音しっかり発音している。」みたいな事まで分かるようになります。

この結果を元に、私が考えてるのはLとRの究極的な区別は絶対音感的な物が関わっているのではないか?と言う事です。音楽が専門の人によると、大人になってからどんなに音楽の練習をしても絶対音感は付かないそうです。その差は年齢だそうで、ある程度の年齢に達すると絶対音感を身に付ける事は出来ないそうです。これに近いものが、LとRの究極的な区別にはあるような気がします。

  • /ʌ/の音はイギリス英語とアメリカ英語で違う

発音記号のもっとも重要な取り決めは「一つのアルファベットに一つの音」です。これは平仮名が言葉の基本単位である日本人には当たり前過ぎる事ですが、英語では、一つのアルファベットに沢山の発音方法があり、また同じ発音を別のアルファベットで共有したりしてるため、アルファベットで音を表す事が出来ません。

その弊害を無くすために開発された発音記号ですので、絶対に「一つのアルファベットに一つの音」の原則は守らなくてはいけないはずなのに、もっとも基本的な音の一つである/ʌ/の音がイギリス英語とアメリカ英語で違います。

  • 発音記号は、音を以下の条件で定義している。ただし2と4は条件付きで、結構曖昧。
    1. 口の開ける大きさ、
    2. 舌の動かし方や位置、
    3. 唇の形、
    4. 息の吐き方(イントネーションやアクセントを含む)

日本人には違う音に聞こえるのに同じ音で表示されている英単語が沢山あります。逆に日本人には全く同じ音なのに違う音として定義されている発音記号もあります。上記の原則を理解しておくと英語圏言語学者は、その上記の原則に照らし合わせて同じ音、違う音として認識しているんだと分かります。

  • Schwa /ə/音について

アメリカ英語の発音指導の専門家の多くは/ə/と/ʌ/は全く同じ音で、/ʌ/は強く、/ə/は弱く発音するだけであると言っています。これは上記の発音記号の定義で、アメリカ英語の/ʌ/と/ə/を当てはめて考えると全くその通りです。

しかし日本人にとってはちょっと違う話で、/ʌ/はどの単語で使用される場合でも、ウに近いアに聞こえるのに対して、/ə/は単語によってはアに聞こえたりオやウに聞こえたりします。

そうなると実際のSchwa音が分からなくなり大変不安になります。

これについてですが、口を全く動かさないで、喉の奥だけでアイウエオと言うと結構アイウエオと聞こえる事と関係していると思っています。

もう少し詳しく説明すると、/ə/が実際の発音で使用されるときは、必ず元の音があって、それの退化した音として使用されます。だから実際に単語の中で/ə/が使用されている場合、口の開ける大きさ、舌の動かし方や位置、唇の形、息の吐き方は/ə/の発音になっていても、喉の奥で発する音は元の音に近い音が発せられていると思われます。

それが実際の単語内の/ə/の音がアに聞こえたりオやウに聞こえたりする理由だと考えています。

  • /ɜ// ɝ //ɚ// ɜɹ// əɹ/は同じ音として扱う

これはRの音についてなんですが、日本語でアを伸ばすとアーになります。イギリス英語だと日本と全く同じで単に音を伸ばすだけなんですが、アメリカ英語だと音を伸ばす時に丸めるんです。音を巻くというともっと正確かもしれません。その巻いた音を日本語で表現するとア~となりますが、この音がアメリカ人にはRに聞こえるらしいんです。つまりアRと聞こえます。それで発音記号は二つのアルファベットで表すべきと考える人と、いやア~と一つの音が伸びているだけだから一つのアルファベットで表すべきと考える人たちがいます。更に単語によってアRと聞こえるものとア~と聞こえると主張する人もいます。

2つのアルファベットで表すべきと考える人は/ ɜɹ// əɹ/を使用しますし、一つの音で表すべきと考える人は/ ɝ //ɚ/を使用します。更に単語によって違うと主張する人達は、単語によって/ ɜɹ// əɹ/と/ ɝ //ɚ/を使い分けたりします。

更に混乱する要素として/ɜ/と/ɚ/はアメリカ英語だと同じ音だったりします。

前提としてイギリス英語だと、/ʌ/は/ə/とは全く違う音です。ので/ə/のストレス音が必要になります。それが/ɜ/らしいのです。しかしイギリス英語では/ɜ/は/ə/より強く発音するだけでなく長く伸ばして発音するらしいんです。つまりアメリカ英語なら丸くなる訳です。それで/ɜ/がストレスのある/ɚ/になる訳です。所がこの強弱ですがアメリカ英語の場合、ほとんど変わりません。つまり同じに聞こえます。

それじゃ最後に/ɜ/と/ ɝ /の違いは何ですかとなりますが、アメリカ英語にもイギリス英語の/ɜ/と同じ音がある。だからRで巻いた時は/ ɝ /を使うべきと言う人達です。彼らによるとBirdなんかはRで巻いていない。と言っています。言っていますがBirdをRで巻いて発音するアメリカ人はいくらでもいるでしょうし、その例えは、何か日本人でもカナダをキャナダと発音する人がいます。みたいなちょっと恥ずかしい感じがします。

これらの音は結局ERの音を表しています。HerとかMotherなどのerです。勿論“英語”ですのでアルファベットと実際の音は限定的にしか繋がっておらず、girlのirやhurtのurはこの場合のerと同じ音です。

ちなみにですが、この音とɑɹの音(例えばHurtとHeart)はどちらも日本語で「ア~」と聞こえますがMinimal Pairで練習すれば5分位でこの2つの音の区別がつけられるようになります。

  • Lの発音はTHみたいに舌を噛んでする

これ、私ずっと疑問に思っていた事なんですが、アメリカ人にLの発音の仕方を聞くと、上歯の付け根に舌をタッチさせてと、所謂教科書的な説明をみんなします。それなのに実際の会話でLを発音する時には、THの時の様に舌を噛んで発音しているんです。

そしたら確認出来ました。沢山のアメリカ英語の発音の専門家がLの発音の時にTHのように舌を噛んで発音する方法もあると言っていました。

それらの専門家の話を聞くまで、この舌を噛んで発音するLはDark Lの音なのかな?とか思ったりもしたんですが、実際はもう少し複雑でした。

Dark Lの音は口の奥、喉側で出す音なので、舌の付け根の形だけが大切だそうです。ので舌を噛んでいてもいなくてもDark Lの音を出す事は出来るそうです。

そしてLight LはDark Lを前半で発音して後半に所謂教科書的な上歯の付け根に舌をタッチさせて発音するそうです。この時に舌の脇から息が抜けるとLの音になり、その時の舌の位置は歯の裏でも舌で歯を噛んでも関係ないそうです。

それで実際の発音の場合ですが、例えばGirlと発音する時はLはDark Lになります。Light Lの前半部分だけ発音する訳です。しかしGirl isと発音する場合は残り後半も発音するのでLight Lになるそうです。その時に最初から舌を噛んで発音するとDark Lの発音で止める事もそのままLight Lの発音に移行する事も舌の先を動かさないで出来るので楽に発音出来るらしいんです。

ふーん。って感じです。

  • 二重母音について

[aɪ], [eɪ], [ɔɪ], [aʊ]のような音を二重母音( diphthong ) と言いますが、これってすごい不思議でした。だって単に母音が二つ並んでいるのと同じじゃないですか?日本語でアオとかアイとかをアイウエオとは別に習う必要はないですよね。なんでこれらの音は特別なんでしょうか?

ずっとその理由があると思っていたんですが無かったです。単にこれらの母音は二つ続けて発音する事が多いだけでした。

ただ気を付けないといけないのはこれらの母音の中に、/a/や/e/の音のように二重母音にしか存在しない音があります。

この辺はまだ勉強中ですが、/a/の音は日本語のアとほとんど同じで、/e/の音は日本語のエの音とこれもほとんど同じに聞こえます。Vowel Chartを見てもこれらの音と日本語のアとエは非常に近いか全く同じ位置に記されています。

  • /ɑ/について

この音、日本語が喋れるアメリカ人で日本語のアの音と同じ音と言っている人達がいます。いますが、これそのまま信じるのはかなり危険だと思います。

私は/ɑ/の音はオの混じったアで単なるアとは違う音だと思います。

その理由は、/ɑ/と/ʌ/の音のMinimal Pair(duckとdock、hutとhot、nutとnotなどです。)で練習すると、日本人なら直ぐに実際の単語の発音では/ɑ/の音にはオが僅かですが完全に聞こえ、それ故に区別が容易につく事に気づくからです。

確かに中にはFatherのようなオが全く聞こえない単語もあります。しかしこれだけ沢山の/ɑ/の音を使用している単語が僅かながらオが聞こえるのですから実際はオに近いアだと思います。

更に言えばVowel chartの記載から見ても、/ɑ/の音は、日本語のアの音とはかなり違う音です。まず日本語のアは口の先で発音しています。それに対してこの/ɑ/の音は口のかなり後ろで発音します。それに日本語のアの音はかなり広い範囲のアの音で、あんまり口を開けないでしゃべるおとなしい女の子なんかはむしろ/ʌ/に近い音でアを発音しています。

もう一つ言うと、一般的な日本語のアに一番近い英語の音は、先程の二重母音に出て来た/a/の音だと思います。

まだまだ書く事はありますが、今週はこの辺で止めておきます。

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

<本文>

1.今週の予定

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

  • 対話システムとアドベンチャーゲーム本形式によるセリフの整理方法の考察
  • Game Modeクラスの整理の続き
  • バグの直し
    • 勝利のポーズの時に剣が頭に刺さる。
    • モンスターが後ろを向いているとプレイヤーの操作するキャラがすぐ後ろに立っていても気が付かない。
    • 戦闘時の武器のモーションの追加
    • 魔法の杖を装備したら名前が枠からはみ出て表示されていたのでそれを直す。
    • 魔法のeffectを増やす。
  • Levelデザイン

2.対話システムとアドベンチャーゲーム本形式によるセリフの整理方法の考察

先週、戦闘時における報連相のための対話システムを一から直しましたが、その際にNPCとの会話で考案したアドベンチャーゲーム本形式によるセリフの管理方法を採用しました。

このやり方は全てのセリフを一枚のData tableで管理出来るだけでなくData Tableを見ればそのセリフの前後関係も把握出来る優れたシステムです。

ここで思ったんですが、実際のゲームではどうやってセリフを管理しているんでしょうか?調べて見ます。

2.1 実際のゲームにおける対話システムの管理方法はどうなっているのかを調べる。

あんまりゲームにおける対話システムの管理方法についての記事がありませんでした。

あるにはあったんですが、何か高校生がまとめたみたい感じのサイトとか、ユーザー側に寄り過ぎてどうやってそのセリフを整理・管理しているかについては全く述べていないサイトばかりでした。

その中でWikipediaにDialogue Tree についての解説が載っていました。

このシステムは、私が採用したアドベンチャーゲーム本形式によるセリフの書き方をTree Diagramに表した方法でした。

やっぱりアドベンチャーゲーム本形式は商業レベルのゲームでも採用される優れたシステムだったんですね。

後、Tree Diagramにすると非常に見やすいです。

ここの説明によるとこの方法が最初に採用されたのは1941年と書かれていました。このやり方を現在のゲームでも採用し続けているのかそれとももっと優れた方法があるのかは書かれていませんでした。

後、ユーザー視点からですが、対話システムの進歩としてWe Should Talkと言うゲームが挙げられていました。

このゲームではNPCとの会話は、複数ある回答の中から一つを選ぶのではなく、文の一部を変更して自分で回答する文を作成するそうです。

f:id:kazuhironagai77:20210315000741p:plain

確かに進歩と言えば進歩ですが、Tree Diagram が出来てから80年以上経っている訳ですから。革命的とまでは言えないですね。

もっと機械学習したAIが回答するみたいなのはないのでしょうか?

調べて見たら、論文は出て来るんですがゲームは出てこないですね。

何か、日本のゲームとか世界の先端を走っているイメージがあったんですが、大人数で開発しているようなゲーム会社でも80年以上前に開発された対話システムをそのまま使用しても何とも思わないでゲーム作っているんですかね。ちょっとがっかりです。

2.2 Not Yet Dialogue Plugin System について

Tree Diagramと言えば、UE4のplugInであるNot Yet Dialogue Plugin Systemは対話をTree Diagramで管理しています。

f:id:kazuhironagai77:20210315000807p:plain

ゲームにおける対話システムの進歩について、あんまり考察する事もないみたいなので、このPlugInの使用方法をここにまとめる事にします。

3.Not Yet Dialogue Plugin Systemの使用方法の解説

Not Yet Dialogue Plugin SystemはUE4用のPlugInで対話のセリフを管理するのに上記で紹介されたDialogue Tree を採用しています。

3.1 無料版について

marketで売られているNot Yet:Dialogue Plugin Systemは5千円以上します。

しかしhttps://gitlab.com/NotYetGames/DlgSystemに行くと無料で公開されています。

f:id:kazuhironagai77:20210315000844p:plain

これって勝手に使用して良いんでしょうか?と心配しながら、ここの説明文を読んだらBinaryファイルにするのに思っていたより手間がかかるので、Binaryファイルはマーケットで販売する事にした。しかしここにある分は完全にフリーで商業も可と説明してありました。

のでここからダウンロードして使用します。

3.2 使用方法のまとめ

公式のTutorial (Dialogue Plugin System - Create your first Dialogue Project Tutorial)で使用方法が説明されていますが、これでもかなり複雑です。こういう使い方の解説は、最低限の機能の紹介に徹するべきだと私は思います。

それで自分でまとめてみました。

  • 準備編
    • Actor クラスを使用したNPCの作成とDlg Dialogue Participantの継承、そしてParticipant Nameの指定
    • ThirdPersonCharacterDlg Dialogue Participantの継承、そしてParticipant Nameの指定
    • 対話の作成とその対話をDialogue BPに落とし込む
  • 本番編
    • 作成したDialogue BPを使用する。
    • 最初のセリフを表示する。
    • 選択条件を表示する。
    • 次のノードに移る。

本番と準備を分ける事で、このプラグインを使用するに当って最低限準備しなければならない事と、使用するに当たって本当に最低限知らないといけない事が区別して理解出来るはずです。

かなり分かり易い説明になると思っています。

3.3 準備編

Not Yet:Dialogue Plugin Systemを使用するためには3つの準備が必要です。

  • Dialogue BP内に実際の対話を書く。
  • 対話に必要なNPCを作成する。
  • Playerの操作するキャラと作成したNPCParticipant Nameをつける(そのためにはDlg Dialogue Participantの継承が必要)。

これらについて解説していきます。

3.3.1 ダウンロードしたDialogue systemをProjectから使用出来るようにする。

このブログを読んでいる人でダウンロードしたPluginの使用方法を知らない人はいないと思いますが一応書いておきます。

まずProjectを作成します。Template はいつも使用しているThird Personにします。

作成したProjectを開き、新しいFolderを作成します。名前は必ずPluginsとします。

f:id:kazuhironagai77:20210315000948p:plain

先程ダウンロードしたファイルを解凍し、このフォルダー内に移します。

f:id:kazuhironagai77:20210315001005p:plain

これだけでProjectから使用出来るようになります。

確認します。

いつもBPを作成する手順で、以下の選択肢を開くとDialogue Systemと表示されていたら、Dialogue systemが使用出来る様になりました。

f:id:kazuhironagai77:20210315001029p:plain

3.3.2 Actor クラスを使用したNPCの作成

まずNPCを作成します。

Actorクラスから派生させたBPを作成します。

f:id:kazuhironagai77:20210315001052p:plain

中を開きSkeletal Meshを追加します。

f:id:kazuhironagai77:20210315001108p:plain

f:id:kazuhironagai77:20210315001115p:plain

NPCが出来ました。

3.3.3 Dlg Dialogue Participantの継承

今度はDlg Dialogue Participantを継承させます。

ToolbarからClass Settingを選択します。

f:id:kazuhironagai77:20210315001136p:plain

するとDetail欄にInterfaceが現れます。

f:id:kazuhironagai77:20210315001152p:plain

Addボタンを押して、Dlg Dialogue Participantを選択します。

そうすると以下の様にDlg Dialogue Participantが表示されます。

f:id:kazuhironagai77:20210315001207p:plain

これでDlg Dialogue Participantが継承出来ました。

3.3.4 Participant Nameの指定

次にParticipant Nameの指定をします。

以下に示した様に、My BlueprintのInterfaceにGet Participant Nameがあります。それをクリックして開きます。

f:id:kazuhironagai77:20210315001237p:plain

それをクリックして開きます。以下の様になっています。

f:id:kazuhironagai77:20210315001254p:plain

このNoneの箇所にこのNPCの名前を入れます。今回はMeNPCとします。

f:id:kazuhironagai77:20210315001310p:plain

3.3.5 同様の方法でThirdPersonCharacterDlg Dialogue Participantの継承を行い、Participant Nameを指定する。

しました。

f:id:kazuhironagai77:20210315001334p:plain

3.3.6 セリフを作成する

Dialogue BPに記入するセリフが必要です。それを作成しました。

f:id:kazuhironagai77:20210315001355p:plain

3.3.7 Dialogue BPを作成し、上記の会話を移す

作成した会話をNot Yet: Dialogue system内に落とし込みます。ほとんどカンで操作しても作成出来ますが、注意しなければならない箇所が幾つかあります。その辺は詳しく解説します。

まずDialogue SystemからDialogue BPを作成します。

f:id:kazuhironagai77:20210315001418p:plain

このDialogue BPこそがNot Yet: Dialogue Systemにおいてセリフの管理を行うクラスです。

名前をMe_dialogueとしました。

f:id:kazuhironagai77:20210315001433p:plain

開きます。

f:id:kazuhironagai77:20210315001453p:plain

このStartノードから会話を作成していきます。

AIの作成で使用したBehavior Treeの時と同じようにこのノードから→を引っ張ります。そしてAdd Speech nodeを選択します。

f:id:kazuhironagai77:20210315001534p:plain

Speech Nodeにセリフを追加します。

f:id:kazuhironagai77:20210315001551p:plain

するとNode側もセリフが表示されます。

f:id:kazuhironagai77:20210315001609p:plain

今度はこのセリフを言うキャラのParticipant nameを追加します。

f:id:kazuhironagai77:20210315001626p:plain

するとセリフと同じようにMeNPCがノード側にも表示されます。

f:id:kazuhironagai77:20210315001641p:plain

同様にPlayerのセリフも追加します。

f:id:kazuhironagai77:20210315001656p:plain

更に会話を追加していきます。

f:id:kazuhironagai77:20210315001711p:plain

この次は選択肢が表示されます。

f:id:kazuhironagai77:20210315001727p:plain

選択肢は以下の方法で作成します。

まず選択肢の答えのためのノードを作成します。

f:id:kazuhironagai77:20210315001744p:plain

矢印を選択します。

f:id:kazuhironagai77:20210315001800p:plain

するとDialogue Graph Node内に以下の内容が表示されます。

f:id:kazuhironagai77:20210315001814p:plain

ここからTextのNextの部分に選択肢の質問を書いて行きます。

最初の選択肢は「武器を買いに来た。」ですので、それを書き込みます。

f:id:kazuhironagai77:20210315001830p:plain

同様に残り二つの選択肢も埋めていきます。

f:id:kazuhironagai77:20210315001848p:plain

f:id:kazuhironagai77:20210315001856p:plain

今度はそれぞれの選択肢が選ばれた場合のセリフを追加します。

f:id:kazuhironagai77:20210315001912p:plain

ですので、

f:id:kazuhironagai77:20210315001928p:plain

となります。

2と3を選択した場合のセリフも追加します。

f:id:kazuhironagai77:20210315001946p:plain

これで全てのセリフをDialogue BPに書く事が出来ました。

Nodeの最後には、End Nodeを追加します。

f:id:kazuhironagai77:20210315002006p:plain

最後にもう一つやる事がありました。

どのノードも選択しない状態でDialogueを見ると以下の様に表示されています。

f:id:kazuhironagai77:20210315002024p:plain

Participant NameがそれぞれMeNPCとPlayerであるクラスの名前をParticipant Classに記入します。

Playerの方は既にThirdPersonCharacterが選ばれています。MeNPCのParticipant Classを選択します。

f:id:kazuhironagai77:20210315002041p:plain

これで準備が完了しました。

3.4 本番編

ここから、今まで作成したモノを使用してゲーム中にセリフを表示させる方法を説明します。

3.4.1 作成したDialogue BP(Me_dialogue)を使用する。

3.3で作成したDialogue BP(Me_dialogue)を使用するためには、そのinstanceを作成する必要があります。

どのBPでもいいのですが、今回はLevel BP内で作成する事にします。dialogue BPのinstanceを作成する関数はStart Dialogueです。

f:id:kazuhironagai77:20210315002107p:plain

Me_dialogueで使用されているParticipant nameを持つクラスのInsntanceをLevel上に配置します。

f:id:kazuhironagai77:20210315002137p:plain

それらのInstanceをMake Arrayに繋げます。

f:id:kazuhironagai77:20210315002159p:plain

3.4.2 最初のセリフを表示する

前節でDialogue BPのインスタンスの作成までは成功しました。そのインスタンスからどうやってセリフを取り出すのかをここで解説します。

取りあえずアクセスを簡単にするためにMe_dialogueのインスタンスは変数MeDialogueにセットします。

f:id:kazuhironagai77:20210315002223p:plain

ここで突然ですがDialogue BPのActiveなノードと言う概念について説明します。

アドベンチャーゲーム本で考えると分かり易いと思うんですが、自分がゲームのどこをやっているのかを表すためには、今、自分が読んでいる文章の番号が必要です。誰か友達にどこまで進んだ?と聞かれたら「今、180でドラゴンと戦っている。」と答える訳です。

この時の180と言う番号は、考えようによっては、今自分が居る場所とも言えます。Dialogue BPでは、この今自分が居る場所をActiveな場所(ノード)と呼んでいます。

勿論、Dialogue BPは対話のセリフなので、Active Nodeは、今どのセリフを読んでいるのかを表します。

f:id:kazuhironagai77:20210315002242p:plain

当然ですが、ActiveなノードはDialogue BP内で一個だけです。

Dialogue BPのインスタンスからセリフを取り出すためには、このActiveなノードにアクセスする必要があります。

Activeなノードにアクセスするために使用する関数はGet Active Nodeです。

f:id:kazuhironagai77:20210315002303p:plain

アクセスしているNodeのテキストを読む関数はGet Node Textです。

I keyを押すとnodeに書かれたテキストをプリントする様にします。

f:id:kazuhironagai77:20210315002319p:plain

すると、Iを押すたびに

f:id:kazuhironagai77:20210315002334p:plain

とプリントされました。

これで現在のactiveなノードのセリフをゲーム画面に表示する事が出来ました。

3.4.3 次のノードに移る

最初のセリフが表示出来たら、今度は次のセリフを表示する必要があります。その為にはActive Nodeを次のノードに移す必要があります。

次のノードに移すための関数はChoose Optionです。

f:id:kazuhironagai77:20210315002403p:plain

次のノードが1つ以上ある場合はOption indexに移動したいノードに着いている矢印の番号を記入します。矢印の番号は0から始まり左から数えていきます。

以下の様に実装してセリフが変化する様子を見てみます。

f:id:kazuhironagai77:20210315002419p:plain

結果です。

f:id:kazuhironagai77:20210315002433p:plain

Iを押すたびにActive nodeが前進して表示されるセリフが変わっています。

3.4.4 選択条件を表示する

最後に矢印に追加したセリフの表示方法を説明します。

f:id:kazuhironagai77:20210315002456p:plain

そのために使用する関数はGet Optionです。

f:id:kazuhironagai77:20210315002510p:plain

矢印の中から一個の矢印を選ぶのがChoose Option関数だから、矢印そのものを収得する場合はGet Option関数であるのは納得です。

正しこの矢印、Text以外にも沢山の情報を持っています。

f:id:kazuhironagai77:20210315002527p:plain

のでその中からTextを選ぶ必要があります。

なので以下の様な実装になります。

これで矢印のテキストにもアクセスする事が出来ました。

f:id:kazuhironagai77:20210315002542p:plain

テストします。

f:id:kazuhironagai77:20210315002557p:plain

あれ。Nextってなんですか?

となるかもしれませんが、

f:id:kazuhironagai77:20210315002709p:plain

矢印は何も指定しないとdefaultでNextが指定されているんです。

問題はそこじゃないんです。

「ここは武器屋です。今日はどんな御用ですか?」の後のセリフを見て下さい。

「武器を買いに来た。」しか選択肢が表示されていません。

選択肢は全部、表示されないと選択出来ませんよね。そこを次の節で直します。

3.4.5 選択条件を全て表示する。

選択肢を全部表示させる関数は…。残念ながらありません。普通のC++のように選択肢の数を調べてその分ループして表示します。

ノードが持つ選択肢の数を調べてくれる関数はGet Option Numです。

f:id:kazuhironagai77:20210315002733p:plain

この関数を使用して以下の様に実装します。

f:id:kazuhironagai77:20210315002750p:plain

結果を示します。

f:id:kazuhironagai77:20210315002805p:plain

はい。選択肢が全て表示されました。出来ました。

3.5 Not Yet Dialogue Plugin SystemのTutorialの作成のまとめ

公式のTutorialをかなり参考にしましたが、自分で作成した初めてのTutorialです。

自分ではこのTutorialが分かり易いのか、あるいは途中で詰まって出来ない箇所があるのか、もしくは興味が持てるほど引き付けられる内容があるのかなどは、全然分かりません。

一応以下の事を考えて書きました。

Hooking (読者を引き付けるための口上)としてこの5000円以上するこのNot Yet Dialogueが無料で手に入る方法を教えています。

このpluginを使用するために必要な事と、使用するための準備に必要な事を、明確に分けるために準備編と本編に分けました。こうする事で読みやすいかどうかは分かりませんが理解はし易くなったと思います。

本編ではActive Nodeと言う考えを最初に説明してそのActive nodeに従ってセリフを抽出していく事を説明しています。この方が分かり易いと思ってそうしました。

更に覚えなければならない関数の数を最小にするためにStart Dialogue()、Get Active Node ()、そしてGet Option()の三つと、その補助としてGet Node Text()、Get Option Num()の二つだけに絞って説明しています。

4.Game Modeクラスの整理の続き

先週、RPGGame Mode BPを整理して思ったのがまだまだ整理出来そうでした。

なので今週の引き続き整理していきます。

4.1 MyGameInstance変数の整理

f:id:kazuhironagai77:20210315002845p:plain

以下の様に整理しました。

f:id:kazuhironagai77:20210315002901p:plain

こんな感じで全部直していきます。

4.2 Third Person Character BP変数の整理

次はThird Person Character変数を直します。

f:id:kazuhironagai77:20210315002930p:plain

4.3 Combat UI変数の整理

Combat UI変数も直します。

CombatUI変数ですが戦闘中に同じウィジェットを三か所もセットしています。

f:id:kazuhironagai77:20210315002955p:plain

既に外していますが、Action状態で二か所です。

f:id:kazuhironagai77:20210315003011p:plain

f:id:kazuhironagai77:20210315003019p:plain

戦闘中にDecision状態でセットされたウィジェットがAction状態になった途端に外れる事はないので、Action状態にあるSETは全部消します。

以下の様に整理していきます。

f:id:kazuhironagai77:20210315003046p:plain

f:id:kazuhironagai77:20210315003057p:plain

f:id:kazuhironagai77:20210315003106p:plain

f:id:kazuhironagai77:20210315003133p:plain

f:id:kazuhironagai77:20210315003143p:plain

f:id:kazuhironagai77:20210315003153p:plain

f:id:kazuhironagai77:20210315003202p:plain

一応確認のためにテストします。

  • 武器なし:負け
  • 武器あり:勝ち
  • 魔法あり:バグで表示されず。

魔法はレベル1では覚えないので、Mを押すと魔法を覚えるように設定していたのですが、下に示したThirdPersonCharachterBPのコードでもMを使用していてこれとぶつかっているみたいです。

f:id:kazuhironagai77:20210315003248p:plain

このコードはワープの時に使用しているコードですが、Mでマップを開く必要ないのでMを外しました。

f:id:kazuhironagai77:20210315003304p:plain

今度は使用可能になりました。

更に一個バグを発見しました。

罠に一回侵入してモンスターを発生させ、その後逃げ出します。するとモンスターが死んで死体が消えるのですが、消える前にもう一度、罠に入ります。

f:id:kazuhironagai77:20210315003322p:plain

するとモンスターは発生しませんが、戦闘は開始します。

直します。

以下の様に改良しました。

f:id:kazuhironagai77:20210315003338p:plain

もしSpawned Monsterに実体が在る場合は待つ事にします。モンスターが消えるアニメーションは1.2秒なので、その間は罠に侵入しても新しいモンスターは発生しないようにしました。

テストします。

f:id:kazuhironagai77:20210315003353p:plain

何十回やっても死体が消えてから新しいモンスターが発生するようになりました。

直りました。

直りましたが、こんな僅かな一手間でバグが跡形もなく消えるのは正直、驚きです。

 

UE4C++でコードを書いていた時は「Buildに掛かる時間ウゼー、BP最高!」と思っていましたが、こうやって整理のためにBPを見直して見ると、BPは直ぐにスパゲッティコードになってしまっていますね。これを見やすいコードに戻すのはかなり難しいかもしれません。

5.バグの直し

先週見つけたバグを直していきます。

5.1 勝利のポーズの時に剣が頭に刺さる。

以下に示した様に剣が頭に刺さっています。

f:id:kazuhironagai77:20210315003503p:plain

調べたら、武器を装備した状態用の勝利のポーズのアニメーションがありました。

f:id:kazuhironagai77:20210315003533p:plain

f:id:kazuhironagai77:20210315003542p:plain

武器を装備した時はこのアニメーションを使用する様にします。

f:id:kazuhironagai77:20210315003559p:plain

テストします。

武器を装備している時は武器の勝利のポーズを取ります。

f:id:kazuhironagai77:20210315003619p:plain

勿論、剣が頭に刺さる様な事はありません。

f:id:kazuhironagai77:20210315003633p:plain

武器がない時は無い時のモーションを取ります。

5.2 モンスターが後ろを向いているとプレイヤーの操作するキャラがすぐ後ろに立っていても気が付かない。

現状のモンスターの視界の広さを示しています。特に狭いとは思えませんね。

f:id:kazuhironagai77:20210315003654p:plain

視界をこの状態より広げればこの問題は解決しますが、それよりモンスターが辺りを見渡す動作を追加した方がリアルな気がします。

色々検討しましたが、回りを見渡すアニメーションがないとどうしても動作が機械的になってしまいます。

別な方法で解決しましょう。

モンスターの視界がかなり狭いみたいです。

モンスターの視界を1500から2500に変更しました。

f:id:kazuhironagai77:20210315003709p:plain

単位が分からなかったから1500でも凄い気がしていましたが、15m先までしか見えてないって近眼でレベルじゃないでしょう。25m先まではプレイヤーの操作するキャラを認知出来るようにしました。

以下に示した緑のサークルがモンスターが認知出来る範囲です。

f:id:kazuhironagai77:20210315003724p:plain

更にIsHeInTerritory Serviceでモンスターの縄張りを決定していますが、その範囲も2500に変更しました。

f:id:kazuhironagai77:20210315003741p:plain

f:id:kazuhironagai77:20210315003748p:plain

最後に休憩時間も2秒から0.5秒に変更しました。

f:id:kazuhironagai77:20210315003805p:plain

これでテストします。

これだけ条件を厳しくするとモンスターの後ろに貼りつくのは無理になりました。

f:id:kazuhironagai77:20210315003822p:plain

ただ、モンスターから見ると休憩時間が4分の一になってしまったので、かなりブラックな職場になってしまいました。

心なしかモンスター達も苛立っているように見えます。

私がモンスターの首を回して辺りの警戒をする方法が分からなかったばかりに、モンスター達のパトロールはかなりハードなものになってしまいました。何かブラックな職場が生まれる原因を見た気がします。

取りあえず解決です。

5.3 戦闘時の武器のモーションの追加

弓を装備した時も、剣の装備した時と同じモーションです。これを直します。

最初、攻撃モーションだけ直せば良いかと思い、それだけ直したんですが、攻撃以外のモーションが非常に不自然だったので全部のモーションを直します。

まず装備が弓と矢の場合とそれ以外を判別するための関数を作成しました。

CheckArrowBow()関数と名付けました。

f:id:kazuhironagai77:20210315003904p:plain

この関数で武器や防具を装備するたびにその装備が弓矢かどうかをチェックします。弓矢の場合は専用のアニメーションを流すようにします。

以下の箇所で武器を装備していますので、その装備が弓矢かどうかをチェックします。

f:id:kazuhironagai77:20210315003922p:plain

そして装備が弓矢だった場合は、MyThirdPersonAnimBPに新しいBoolean変数を作成して下の部分から更に分岐させます。

f:id:kazuhironagai77:20210315003938p:plain

最初のSet Weapon Equipped()関数が呼ばれている箇所ですが、StartScreenで使用していました。

f:id:kazuhironagai77:20210315003954p:plain

この時にCheckArrowBow()関数でチェックして、mapが変わったら全部消えてしまうので、ここでチェックする意味はありません。代わりにRPGGameModeBPのEvent Begin Playでチェックしましょう。

f:id:kazuhironagai77:20210315004009p:plain

ついでにMy Third Person Anim BPに弓矢を装備した事を知らせる変数、Bow And Arrowも作成しました。

Anim Graphのdefaultでは以下のStateを追加しました。

f:id:kazuhironagai77:20210315004024p:plain

弓と矢を装備した状態でも魔法を使用する事もあるので上記のような形になりました。

他のSet Weapon Equipped()関数が呼ばれている箇所も同様にします。

Weapon Widgetの場合です。

f:id:kazuhironagai77:20210315004040p:plain

Is Weapon Equipped変数の後で、My Third Person Anim BPのwithWeapon変数の値をTrueに変更しているので、その後でCheck Arrow Bow()関数を呼びました。

f:id:kazuhironagai77:20210315004058p:plain

次は、pause画面で武器や防具を外した時の場合です。(Pause Equipment ウィジェット)

f:id:kazuhironagai77:20210315004116p:plain

武器と防具のどちらか一方でも外せばその時点で弓矢を装備していない事は確定なのでCheckArrowBow()関数を使用する必要はありません。

f:id:kazuhironagai77:20210315004134p:plain

これで、新しいマップが開かれた時、武器を装備した時、武器を外した時に、弓矢を装備しているのかどうかをチェックします。

防具を装備した時、外した時の場合も上記のコードが、弓矢を装備しているのかどうかをチェックしますので、新しくコードを追加する必要はないはずです。

今度は、弓矢を装備している場合のアニメーションの作成をします。

武器を装備した状態のIdle、Walk、そしてRunのアニメーションを管理しているMyThirdPerson_IdleRun_2DwithWをDuplicateしてMyThirdPerson_IdleRun_2DwithBowArrowを作成し、中のアニメーションを弓矢のそれにします。

f:id:kazuhironagai77:20210315004156p:plain

デモ画面では刀が頭に刺さっていますが、弓矢に交換したら直るんでしょうか?

作成したアニメーションをMy Third Person Anim BPのIdle/Run And Arrowから呼び出します。

f:id:kazuhironagai77:20210315004211p:plain

f:id:kazuhironagai77:20210315004218p:plain

弓矢で攻撃するモーションも追加します。

f:id:kazuhironagai77:20210315004235p:plain

f:id:kazuhironagai77:20210315004241p:plain

これで完成です。

テストします。

弓矢を装備します。

f:id:kazuhironagai77:20210315004257p:plain

中々カッコイイですね。

装備を外します。

f:id:kazuhironagai77:20210315004317p:plain

弓だけ装備します。

f:id:kazuhironagai77:20210315004339p:plain

はい。弓だけだと弓矢のアニメーションにならないですね。出来ています。

矢だけでも同様です。同様ですが、矢の先が地面にめり込んでいます。このアニメーションは直す必要があります。後で直します。

f:id:kazuhironagai77:20210315004404p:plain

この後、色々な条件で試しましたが、全部出来ていました。

今度は戦闘時のアニメーションをチェックします。

弓矢を装備した時は、弓矢のアニメーションになっています。

f:id:kazuhironagai77:20210315004420p:plain

問題はこの状態で魔法を使用した時です。

魔法を試すために一端、ゲームを終了したら、Errorが出ている事に気が付きました。

f:id:kazuhironagai77:20210315004436p:plain

これは武器や防具を片方だけ外した時に発生したエラーのようです。

エラーが発生した箇所のコードを見直すと、MyThirdPersonAnimBPにアクセス出来ていない事が判明しました。

直しました。

以下に示した黄色で囲った部分を追加しました。

f:id:kazuhironagai77:20210315004511p:plain

これでエラーは出ないはずです。

テストして確認します。

片方だけ武器や防具を変更したり、外したり、装備したりしましたがerrorは出ませんでした。

直っています。

それでは魔法のテストをします。

まず弓矢を装備した状態で魔法を使用しました。

f:id:kazuhironagai77:20210315004528p:plain

普通に使用出来ました。

魔法の使用後は、弓矢のモーションに戻っています。

f:id:kazuhironagai77:20210315004544p:plain

今度は弓矢で攻撃します。

f:id:kazuhironagai77:20210315004603p:plain

普通に弓矢で攻撃しました。

又、魔法で攻撃します。

f:id:kazuhironagai77:20210315004618p:plain

出来ていますね。

ああ…

勝利のポーズが弓矢のそれではなかったです。

直します。

f:id:kazuhironagai77:20210315004638p:plain

これで勝利のポーズも弓矢のそれになるはずです。

テストします。

f:id:kazuhironagai77:20210315004653p:plain

手から弓が離れていますし、矢が地面に刺さっています。

これが本当に正しい勝利のポーズなんでしょうか?

デバックした限りでは正しい様です。

f:id:kazuhironagai77:20210315004727p:plain

ここで流しているVictory_Bow_Animの元のアニメーションをチェックしましたが、モーションは同じでした。

f:id:kazuhironagai77:20210315004741p:plain

多分合ってはいますね。

今回はここまでとして、アニメーションのおかしい所は、後で検討しましょう。

先週のブログを読み直したら、

f:id:kazuhironagai77:20210315004756p:plain

と書かれていました。

これも後で検討します。

5.4 魔法の杖を装備したら名前が枠からはみ出て表示されていたのでそれを直す。

単純に後ろの絵を引き伸ばしました。

f:id:kazuhironagai77:20210315004817p:plain

それよりもSoldierの表示はオカシイです。

こっちも直します。

f:id:kazuhironagai77:20210315004835p:plain

はい。出来ました。

5.5 魔法のeffectを増やす。

今回は、魔法の炎(小)を作成するだけにします。

Effectは大変大きな分野で、バグの直しの一環で全部を勉強出来る訳はなかったです。

改めて時間を作って勉強する事にします。

更に今はParticle Systemで作成していますが、Niagaraを勉強すべき時が来ているのかどうかも調査しようと思います。

Fire Ballのサイズが小さいversionを作成しました。

f:id:kazuhironagai77:20210315004858p:plain

実際に使用したら、何故か同じサイズの火の玉が飛び出してきました。ので以下の方法で炎(小)を作成しました。

f:id:kazuhironagai77:20210315004918p:plain

FireBallをSpawnする時にそのサイズを指定します。炎(小)の時はサイズを0.25倍にしました。

炎(小)の場合、

f:id:kazuhironagai77:20210315004936p:plain

f:id:kazuhironagai77:20210315004944p:plain

炎(大)の場合はいつもと同じです。

f:id:kazuhironagai77:20210315005000p:plain

6.Levelデザイン

以下の地図通りに作成します。

f:id:kazuhironagai77:20210315005023p:plain

サイズはどうしましょうか?

先週のスピードに関する調査でマップの大きさも分かりました。

島の全体を見るのに歩いて1時間もかかったら面白く無くなります。精々10分で全体が見れるべきです。300m^2位にしますか。

調べて見た所、前回作成したLandscapeの大きさが127m^2でした。

f:id:kazuhironagai77:20210315005103p:plain

町の大きさが127m^2で普通なのに、島の大きさが300m^2では小さすぎますね。

Landscape Technical Guideによるとお勧めのサイズは以下の様になっています。

f:id:kazuhironagai77:20210315005120p:plain

1009m^2にしておきますか。

どっちを選択しましょうか。

f:id:kazuhironagai77:20210315005140p:plain

f:id:kazuhironagai77:20210315005147p:plain

Component Edge、Section Edgeそして Individual Quadについての軽い復習をしてから決める事にします。

2020-11-08のブログにLandscapeについてまとめがありました。

読んでみると結構重要な事が書かれていました。

f:id:kazuhironagai77:20210315005206p:plain

最小単位は1㎝もしくは1 Unreal Unitなんでしょうか。

前回作成したLandscapeは一辺のサイズがだいたい130mでした。

そして以下の表の下のパラメーターで作成しました。

f:id:kazuhironagai77:20210315005222p:plain

63x2=126で1を足して127、127mだとすると、最小単位は1mですね。

Component、Sectionについての解説がLandscape Technical Guideに載っていました。

それによるとComponentはrendering, visibility calculation, そして collisionを計算する単位だそうです。

RenderingとCollisionは分かりますが、Visibility Calculationは何を計算しているのでしょうか?

直接、Visibility Calculationが何を指しているのかを説明しているサイトは見つからなかったですが、色々なサイトを読んで総合的に判断するとCullingのような事を指しているみたいです。

後、もう一つ大切な事は、一つのComponentが一つのHight Map用のTextを保持しています。これはSectionの数とPerformanceに影響します。

SectionはLandscape LOD calculationの単位みたいです。LODはLevel of Detailsの事です。

このSectionの数を増やすと、1枚のテキストで対応するHight Mapの大きさも増えます。つまりパフォーマンスが向上します。

なるほど。

良く分かりました。

後、Epic社はComponentの数は1024 以下にすべきと忠告しているそうです。

ちょっと時間が無くなってしまったので今週はここまでとします。

7.まとめと感想

今週は以下の事をやりました。

  • 対話システムとアドベンチャーゲーム本形式によるセリフの整理方法の考察
  • Not Yet Dialogue Plugin Systemの使用方法の解説
  • Game Modeクラスの整理の続き
  • バグの直し
  • Levelデザイン

対話システムに関してはこれ以上現状ではやる事は無いです。

Game Mode BPクラスの整理はほぼやり尽くしましたが、沢山あるWidgetクラスも同様に整理する必要があります。こっちもやって行こうと思います。

バグの直しでeffectはとてもバグの直しの範囲では対応出来ないので別に枠を作ってやる事にします。

Level デザインは来週やります。

来週やる事は、

  • Level デザイン
  • Widget内のBPの整理
  • Effectの勉強と作成

です。

 

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する バグ出しの続き

f:id:kazuhironagai77:20210307231748p:plain

<前文>

センシティブな同人アニメ絵とアメリカからの圧力による規制について

アメリカに10年住んでいた関係でアメリカの本当の政治事情に詳しい私が予言しますが、これから同人絵のようなセンシティブなアニメ絵に対してアメリカ政府が日本政府に規制するように圧力をかけて来る事はないです。

これは日本のアニメ、特に深夜アニメはポル〇であると断定し、積極的に規制するよう日本政府に圧力をかけていたアメリカの宗教右派がトランプが失脚した事により権力を失ったからです。

アメリカの宗教右派が、日本の同人アニメの絵を規制しないといけない表向きの理由は、彼らの宗教が欲情する事自体を罪にしているからです。しかしその本当の理由は、宗教とは関係なく、有色人種の男性がちょっとでも白人女性に欲情したら使用人として使えないからです。彼らは元々、農場のオーナーなんです。つまりいっぱいいる小作人や使用人を管理する事が彼らにとっての仕事なんです。昔、中国の後宮で働く男性は、宦官にならなければならなかったですが、それと同じ事をやると世論の批判を浴びるので、心理的、精神的に追い込む事で実質、宦官にして使用人にする訳です。そのために欲情する事自体を罪にしている訳です。

アメリカの宗教右派の連中は、日本人全体を彼らの使用人みたく思っていますから、同人アニメの絵の存在そのものを叩く訳です。

これから4年から8年の間、アメリカの政治を司る左派の連中は、元々都会で働くサラリーマンですので、そんな事を考える人は全くいません。むしろ、宗教右派に対して「日本人を使用人にするよりお前のボスにした方が経営上手く行くんじゃないの。」と言う位の連中です。

だから左派の連中がアメリカの政治の中枢にいる限り、日本の同人アニメの絵を叩く事は考えられません。

ただし左派にも僅かにですが同人絵のようなセンシティブなアニメ絵を規制すべきと考える人はいて、彼らが何かのアクションを取る可能性はあります。しかし絶対数が少ないので大した問題にはならないと思われます。

更にアメリカでも、アニメで育った世代が成人となりつつあります。

彼らの中で同人アニメの絵で生計をたてる人も必ず出て来ます。そうなったら規制どころではないです。マリファナですら自分たちに利益をもたらすなら合法化する国が、同人アニメの絵が自分達の利益になった時、180°今までの意見を変えてくるっと賛成派になるのは目に見えています。

そういう訳で、これから同人絵のようなセンシティブなアニメ絵に対してアメリカ政府が日本政府に規制するように圧力をかけて来る事はないと思われます。

ただし、気を付けないといけないのは、これからナチ関係の書籍は逆に大変厳しい規制が課せられたり、賛同するような意見を書いた作者に信じられない位の厳罰が課せられたりするようになると思われます。

先月の前文で説明した通りGenocideの思想そのものがない日本で、本気でナチズムを信じている人はいません。しかしUFOやオカルト本の影響で軽い気持ちで賛同するような意見を書く人はいます。もし貴方の周りにいたら絶対止めるべきです。絶対に最悪な方に誤解されるからです。

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

<本文>

1.今週の予定

以下の事をやって行きたいと思います。

  • モンスターの歩く速度の設定がアニメーションとAIで全然違う
  • BGMの変更、町や村、モンスターが居る廃墟で別々のBGMにする。
  • BPの整理。RPGGameModeBPを整理します。
    • そこら中でThirdPersonCharacter変数に値をセットしている。過去、EventBeginPlay関数がBPから呼べなかったので毎回呼び出していた。これを直す。
    • 戦闘システムから呼ばれるEventを整理してまとめる。
  • セリフシステムの整理。確認出来るだけで3種類以上の方法でセリフを管理している。これを統一する。
  • 更なるバグだし。せめて1時間はこのゲームで遊んでバグ出しする。(今週は10分だった。)
  • Levelデザイン。

2.アニメーションとAIにおけるモンスターの歩く速度の設定の検証

Monsterが使用しているAIではMonsterの歩く速度を150に指定しています。

f:id:kazuhironagai77:20210307231912p:plain

一方で、Monsterが使用しているアニメーションでは歩くアニメーションは85でセットされています。

f:id:kazuhironagai77:20210307231932p:plain

実際は歩き始めるモーションを100%使用し始める速度が85で、そこからは歩くモーションと走るモーションのブレンドになります。

移動する速度が345を超えると100%走るモーションに変わります。

実際の速度が150の時の移動のモーションを見ると、そんなに不自然ではありません。

f:id:kazuhironagai77:20210307231952p:plain

ここで検証したい事は、この二つの速度は同じ単位なのか?もし同じ単位ならその単位は何なのかについてです。

もう一つ検証したい事は、モンスターが探索している時、微妙に浮いている気がする事です。

f:id:kazuhironagai77:20210307232013p:plain

この辺も直せたら直したいです。

2.1 UE4の速度の単位

それではこれから調べて行きましょう。

まずAIの方ですが、モンスターの移動スピードはMonsterBPのCharacter MovementのMax Walk Speedが担当しています。

f:id:kazuhironagai77:20210307232042p:plain

Character Movement:WalkingのMax Walk Speedの設定をみると600.0にセットされています。

f:id:kazuhironagai77:20210307232104p:plain

この単位を探してみましょう。

UE4 Answer Hubのこのサイトで質問されていました。

f:id:kazuhironagai77:20210307232148p:plain

質問者はUU/Sが単位でdefaultでは1UU が1cmなので㎝/sが単位ではないかと予測しています。ただしソースは見つかっていないと言っています。

まずここでの議論で、当たり前のように使われているUUの意味が分からないです。Defaultの1UUは1㎝とか言っています。

UUの意味を調べます。

どうやらUnreal Unitsの意味らしいです。ただし参考で出て来た資料がUE3の時代のものでした。

その後「UE4ではUUは1cmに設定された。」とか「World Settingsで値を変更出来る」とかの断片的な情報は出て来ましたが、確認までは出来ませんでした。

特に、World Settingの項目は以下に示した様にVRの項にあって、普通のゲームにも使用されるのか不明です。

f:id:kazuhironagai77:20210307232207p:plain

ただ100 cmは1 mなので完全に違うとも言い切れないのが難しい所です。

もしMax Walk Speedの単位がcm/sだとしたら6 m/sです。秒速は感覚的に分かりづらいですが、少し速すぎないでしょうか?

色々調べてみたら、大体、日本の高校生の100m走の平均は14秒だそうです。そうすると100 m ÷14 sで7.14 m/sになります。ので6 m/sが速すぎると言う事はないですね。

何か、cm/sで合っている気がしてきました。

この質問に対してのコメントで、実際にゲーム内で100m走って速度を測った人がいました。20回測って平均は5.9 m/sになったそうです。6 m/sに大変近い値です。となるとcm/sがMax Walk Speedの単位である可能性は高いですね。

所がこの質問に対する回答で、スピードは実際はSecondに負っているのではなくFrame rateに負っているから、単純にSecondには変換できないと主張する人がいました。

確かにFrameに負うのはその通りですが、前にUE4のDelta Timeの違いの影響を測定したら差がなかったです。

どの週のブログで測定したのかは覚えていないですが、今100m走の秒速などを計算するためにエクセル開いたら、その時のデータと図だけ残っていました。

ので図だけ貼っておきます。

f:id:kazuhironagai77:20210307232228p:plain

これらの結果から推測するとMax Walk Speedの単位がcm/sであるのはかなり正しそうです。

100m走をUE4内でやるのは面白そうですね。

これは試してみましょう。

良く見たら一目盛り1mと書かれていました。

f:id:kazuhironagai77:20210307232247p:plain

これは簡単に100mが作れますね。

走って見ました。

f:id:kazuhironagai77:20210307232306p:plain

100m走るのに16.809秒かかりました。

計算すると5.949 m/sでした。20回測定して平均を出します。

f:id:kazuhironagai77:20210307232322p:plain

ほとんど時間が変わらないので3回で中止しました。

結果は約5.95m/sです。

多分同じ結果になるんでしょうが、Animationの方も確認します。

Animationの方は、Animation BPであるSkelSwordAni BPで以下の様に設定されていました。

f:id:kazuhironagai77:20210307232340p:plain

Get Velocityノードが何の値を取り出しているのか分かれば、Max Walk Speedの単位と同じであるかどうかが判明出来ますね。

取りあえずどんな説明しているのか、カーソルをノードに添えてみたら、思いっきり説明されていました。

f:id:kazuhironagai77:20210307232357p:plain

Cm/s、つまりUnreal Units/secondと書かれていました。

図らずもAIで使用しているMax Walk Speedの単位とAnimationで使用しているGet Velocity関数の単位が同じであるだけでなく、Max Walk Speedの所で推測したUnreal Unitsの単位が㎝である事と、その速度を測るために秒を測っている(frameではなく)と言う事までも正しい事も分かりました。

これだけ解れば十分ですね。テストなら満点です。

次に行きましょう。

2.2 探索時、モンスターが微妙に浮いている気がする。

これは単純にCollusionを担当するCapsule ComponentがMonsterのMeshより下に飛び出ているからでしょう。

確認すると僅かにですが確かに飛び出していました。

f:id:kazuhironagai77:20210307232426p:plain

直します。

直しましたが、モンスターの動きを見るとまだオカシイです。

スクリーンショットではうまく伝わらないんですが滑っている感じがします。

f:id:kazuhironagai77:20210307232443p:plain

理由が分かりました。

歩いている歩幅に対して実際に進んでいる距離が短すぎるんです。今の2倍位は進むべきです。

85が歩く速度に設定されていますが、どうなんでしょうか?

調べて見ると成人だと1分間で80m歩く位が普通だそうです。1.34 m/sでした。となると134 cm/sですから、歩くを85にセットしていたのはかなり遅いかもしれません。

SkelSword1Dでモンスターの歩く速度を130に変更しました。

f:id:kazuhironagai77:20210307232502p:plain

前より滑ってる感じは無くなりました。かなり良くなってはいます。完全に滑っていないとは言えませんが、これだけ改善されたら十分と思います。

f:id:kazuhironagai77:20210307232518p:plain

3.BGMの変更、町や村、モンスターが居る廃墟で別々のBGMにする

これはLevel designが完成してからやります。ので今回はスキップします。

 

4.BPの整理。RPGGameModeBPを整理します。

4.1 昔、BPからEvent Begin Play関数が呼べなかったので、event毎にThirdPersonCharacter変数に値をセットしていた。これを直します。

まずAnimation for Victoryにありました。外します。

f:id:kazuhironagai77:20210307232606p:plain

Game Overにもありました。外します。

f:id:kazuhironagai77:20210307232623p:plain

Moving Camera Positionの所です。外します。

f:id:kazuhironagai77:20210307232641p:plain

Event Report Character Level Upの所です。外します。

f:id:kazuhironagai77:20210307232658p:plain

テストします。

モンスターと戦闘して勝利しました。レベルも上がりました。エラーの表示が出たりゲームが中断したりする事もありませんでした。

念のためにモンスターと戦闘して負けてみました。単にゲームオーバーになっただけでした。

外しても何の問題も起きませんね。

4.2 戦闘システムから呼ばれるEventを整理してまとめる。

以下に示したのが現在RPGGameModeBP内にあるEventです。

黄色に囲って在るEventの全てが戦闘に関係しています。

f:id:kazuhironagai77:20210307232731p:plain

これらを整理していきます。

以下の様に整理しました。

戦闘に関係のないEvent Begin PlayとEvent Tick 関数をまとめました。

f:id:kazuhironagai77:20210307232752p:plain

f:id:kazuhironagai77:20210307232800p:plain

戦闘に関するEventは以下の様に整理します。

  • Decisionに関係するEvent
  • Action に関係するEvent
  • 戦闘後のVictoryGameOverなどに関係するEvent
  • それ以外のEvent

Decisionに関係するEventです。

f:id:kazuhironagai77:20210307232833p:plain

f:id:kazuhironagai77:20210307232841p:plain

Actionに関係するEventです。

f:id:kazuhironagai77:20210307232900p:plain

f:id:kazuhironagai77:20210307232909p:plain

戦闘後のVictory、GameOverなどに関係するEventです。

f:id:kazuhironagai77:20210307232928p:plain

f:id:kazuhironagai77:20210307232942p:plain

それ以外の関数で戦闘に使用するものです。

f:id:kazuhironagai77:20210307233001p:plain

f:id:kazuhironagai77:20210307233011p:plain

全部で12個でした。

あれ、2つ足りません。

Confirmed Button Is Clicked EventはDecisionの中にありました。

f:id:kazuhironagai77:20210307233032p:plain

同様にConfirmed Button Is Clicked 2EventはActionの中にありました。

f:id:kazuhironagai77:20210307233048p:plain

雑と言えば雑ですが一応整理出来ました。

5.対話システムの整理。確認出来るだけで3種類の方法でセリフを管理している。これを整理する。

5.1 対話システムの確認

今まで作成した対話システムの確認をします。

5.1.1 NPCとの対話

まず、NPCとの会話です。

全てのNPCとの会話はStructであるNPC_ConversationBaseを元にして作成しています。

f:id:kazuhironagai77:20210307233128p:plain

NPC_ConversationBaseはTestタイプの変数とAnswer Comment ManagementタイプのArrayで構成されています。

f:id:kazuhironagai77:20210307233150p:plain

Answer Comment ManagementはStructです。

f:id:kazuhironagai77:20210307233206p:plain

中身はInteger型であるJumpToCommnetとText型であるAnswerCommnetで構成されています。

f:id:kazuhironagai77:20210307233223p:plain

実際のNPCにおける使用は以下の様になります。

f:id:kazuhironagai77:20210307233239p:plain

内容にはこれ以上は深入りしませんが、会話を管理するには非常に優れたシステムとなっています。

5.1.2 店主との対話

次に店主との対話システムです。これは教科書に書かれていた方法をそのまま使用しています。

まずNPC_ParentというWidgetを作成してこれに全ての対話を保持させます。

f:id:kazuhironagai77:20210307233303p:plain

Text型のarrayを作成してそれぞれの店主に対応したセリフを保持させます。

f:id:kazuhironagai77:20210307233322p:plain

実際の保持されているセリフです。

f:id:kazuhironagai77:20210307233342p:plain

このWidgetクラスから子クラスを作成してその子クラスにそれぞれの店主との会話を担当するWidgetにします。

その子クラスからNPC_Parentにある対話用のarrayにアクセスさせ実際の会話に使用します。(以下の様な方法でアクセスします。)

f:id:kazuhironagai77:20210307233431p:plain

この方法では「5.1.1 NPCとの対話」でやったやり方のように、答えの選択が複数ある場合には対応できませんが、それ以外ではまあまあなシステムです。

例えば全てのセリフをNPC_Parentで管理しているので全てのセリフをチェックしなければならない時はNPC_Parentを見れば良いからです。

Widgetを継承するやり方は3種類位勉強しましたが、ここで採用されているやり方でPackaging まで出来るのか不明です。ちょっと心配です。

5.1.3 戦闘システムにおける報連相

以下の方法で管理されています。

f:id:kazuhironagai77:20210307233454p:plain

この方法の何が最悪であるかと言うと、セリフの一括管理が出来ない事です。更にそれ故に対話の流れがセリフからだけでは分からなくなります。

しかしこのシステムから提供されるセリフは、ユーザーからは絶対に必要なものです。何故からそれはユーザーに対する戦闘における報告、連絡、そして相談を担当しているからです。

それでこの戦闘システムの報連相の機能は一切なくさないで、実装方法とセリフの管理方法だけ変更したいんです。

5.2 戦闘システムにおける報連相の全容を確認する。

この戦闘システムの報連相の機能は一切無くさないで、実装方法とセリフの管理方法だけ変更するためにはどうすればいいでしょうか?

取りあえず最初にする事は全容を把握する事です。

そこから始めます。

まず前節で示した戦闘システムの一番最初に出て来る報連相を見ると、セリフをCombat Window ウィジェットのComment Text Contentにセットしています。

f:id:kazuhironagai77:20210307233519p:plain

Combat Window ウィジェットのComment Text Contentを調べます。

調べようとしたらCombat Window ウィジェットのBPがゴチャゴチャしていたので整理をします。

f:id:kazuhironagai77:20210307233536p:plain

以下に示したように整理しました。

f:id:kazuhironagai77:20210307233553p:plain

戦闘前、戦闘システムのDecisionの状態で実行されるEvents、戦闘システムのActionで実行されるevent、最後に「読みましたボタン」を押した時に実行されるEventです。

最初のブロックである戦闘前ですが、ここではComment Text Content変数は全く使用されていないのでこのブロックは無視します。

f:id:kazuhironagai77:20210307233611p:plain

次のDecisionブロックですが、Decisionで決定すべき、攻撃、魔法、アイテム、そして逃げるの4つの選択をした後にそれぞれ実行するコードが書かれています。

f:id:kazuhironagai77:20210307233626p:plain

f:id:kazuhironagai77:20210307233633p:plain

f:id:kazuhironagai77:20210307233641p:plain

攻撃を選択した場合、Comment Text Content変数に関しては以下のTextが追加されます。

f:id:kazuhironagai77:20210307233658p:plain

魔法を選択した場合、Comment Text Content変数に関しては以下のTextが追加されます。

段々、分かって来ました。このComment Text Content変数はDecision状態のユーザーと敵のモンスターの選択した内容を報告するためのセリフを管理するためのものだったんです。

f:id:kazuhironagai77:20210307233734p:plain

こんどはItemを選択した時です。

魔法を選択した時と全く同じです。

f:id:kazuhironagai77:20210307233806p:plain

逃げるを選択した時です。

逃げるを選択した時はここで、Comment For Execute Action変数にもセリフを追加しています。

f:id:kazuhironagai77:20210307233824p:plain

ここはDecisionで選択された結果に対しての実行なのでActionですべき事をここでやってしまうのは、論理的にオカシイ気がしますが、この辺は後で検討しましょう。

ここまで来てComment Text Content変数に保持されているTextは何時、Combat UI ウィジェットのコメント欄に反映されるのかと思ったら、

f:id:kazuhironagai77:20210307233843p:plain

直ぐに反映される仕組みになっていました。

f:id:kazuhironagai77:20210307233859p:plain

確認のために戦闘してみます。

f:id:kazuhironagai77:20210307233918p:plain

f:id:kazuhironagai77:20210307233927p:plain

攻撃を選択しました。

f:id:kazuhironagai77:20210307233956p:plain

攻撃の対象にゴブリンを選択しました。

f:id:kazuhironagai77:20210307234013p:plain

f:id:kazuhironagai77:20210307234021p:plain

Decisionの状態はここまでで、残りはAcitonの状態のはずです。

一応確認するために次のコメントも見ておきます。

f:id:kazuhironagai77:20210307234040p:plain

はい。Actionの状態です。

兎に角、Comment Text Content変数に保持されているTextは直ぐにCombat UI ウィジェットのコメント欄に反映されている事は確認が取れました。

5.3 Comment Text Content変数と戦闘システムにおける報連相の管理方法のまとめ

まだ「5.2 戦闘システムにおける報連相の全容を確認する。」の途中ですが、ここまで整理して来て戦闘システムにおける報連相の管理方法についてのアイデアが出ました。のでここでまとめておきます。

今までずっとComment Text Content変数が、戦闘システムのセリフを管理しているにもかかわらず、その内容はその場その場で管理しているので、戦闘システムにおけるセリフの全体像が把握出来ないという問題がありました。

今回、その問題を解決すべく大々的に戦闘システムのセリフの整理、検討を始めたのですが、ここに来てComment Text Content変数が戦闘システムのセリフを管理しているのではなく、実際は、どの変数も戦闘システムにおけるセリフは管理していないという事が分かりました。

実際、戦闘システム内の個々のセリフは以下の方法で、その場その場で追加されているだけです。

f:id:kazuhironagai77:20210307234102p:plain

と言う事は、これらのセリフを一括で管理するData SheetもしくはTextのArrayを作成して、そこからこのAppendにセリフをパスするように変更すればいいんです。

そうすれば、戦闘システムのセリフを一括で管理する変数が出来ます。

それを作成しましょう。

5.4 戦闘システムのセリフを一括で管理するData Sheet

NPCのセリフの管理で使用したNPC Conversation Baseを使用して戦闘システムのセリフを一括で管理するData Sheetを作成しましょう。

f:id:kazuhironagai77:20210307234124p:plain

これならどこでどんなセリフをいうのか一発で分かりますし、そのセリフに対しての解答とその解答を選択した結果に対してのセリフの関係性も一瞬で分かります。

試してみましょう。

以下に示した様に最初の部分だけ作成しました。

f:id:kazuhironagai77:20210307234139p:plain

ここからセリフを読み取って戦闘システムのセリフが作成されるようにします。

RPGGameModeBPのBeginPlay関数に以下のコードを追加します。

f:id:kazuhironagai77:20210307234216p:plain

これでCombat Dialogue変数にCombat Dialogue data tableの全ての名前が保持されます。

次にCombat UIウィジェットのEvent Constructに以下のコードを追加します。

f:id:kazuhironagai77:20210307234234p:plain

これでComment Text Comtent変数にCombat Dialogue data tableの最初のセリフである「戦闘が開始されました。」がセットされたはずです。

テストしてみます。

Comment Text Comtent変数に入っていたDefaultを「戦闘が開始されました。」を「Test」に変更します。

f:id:kazuhironagai77:20210307234250p:plain

f:id:kazuhironagai77:20210307234258p:plain

これでCombat Dialogue data tableからセリフが読み込まれた場合は「戦闘が開始されました。」が表示されCombat Dialogue data tableからセリフが読みこまれなかった場合は「Test」が表示されるはずです。

f:id:kazuhironagai77:20210307234318p:plain

「戦闘が開始されました。」が表示されました。

出来ています。

しかし完璧ではありませんでした。

段落が無くなってしまっています。

f:id:kazuhironagai77:20210307234335p:plain

直します。

Combat UIウィジェットのGet Comment Text Box関数を以下に示した様に変更します。

f:id:kazuhironagai77:20210307234351p:plain

これでComment Text Content変数のtextに{nextline}が使用されていた場合、段落に変換されます。

更にCombat Dialogue data tableの最初のセリフである「戦闘が開始されました。」に{nextline}を追加しました。

f:id:kazuhironagai77:20210307234416p:plain

テストします。

f:id:kazuhironagai77:20210307234434p:plain

今度は行替えされて表示されています。

出来ました。

次は以下のセリフの交換になります。

f:id:kazuhironagai77:20210307234450p:plain

ここで気が付いたんですが、Combat Dialogue data tableのセリフが少し間違えていました。

直します。

Playerの操作するキャラとモンスターではNewRow_0のセリフは前半部は同じですが後半は違いました。ので二つに分けました。

f:id:kazuhironagai77:20210307234507p:plain

それでは最初の部分のセリフである「“は次の行動を考えています。」をCombat Dialogue data tableから読み込む事にします。

以下に示した様に改良しました。

f:id:kazuhironagai77:20210307234531p:plain

テストします。

f:id:kazuhironagai77:20210307234551p:plain

出来ています。

今度は「{表示されているボタン(攻撃、逃げるなど)の中から一つ選択してください。}」を変えます。

f:id:kazuhironagai77:20210307234611p:plain

テストします。

f:id:kazuhironagai77:20210307234628p:plain

出来ていますね。

行替えは出来てなかったのでそこだけ直しました。

整理しましたがまだまだスパゲティです。

f:id:kazuhironagai77:20210307234645p:plain

セリフをCombat Dialogue data tableから読み込む部分は関数にしますか。

四角で囲った部分です。

f:id:kazuhironagai77:20210307234704p:plain

関数名はGet Dialogue From Combat Dialogue DTです。

f:id:kazuhironagai77:20210307234720p:plain

かなり見栄えも良くなりました。

他の部分も直していきます。

以下の様に直しました。

Combat Dialogue data tableのセリフは以下の様に成りました。

f:id:kazuhironagai77:20210307234741p:plain

以下に実装部を示します。

f:id:kazuhironagai77:20210307234809p:plain

f:id:kazuhironagai77:20210307234816p:plain

f:id:kazuhironagai77:20210307234825p:plain

f:id:kazuhironagai77:20210307234833p:plain

f:id:kazuhironagai77:20210307234842p:plain

f:id:kazuhironagai77:20210307234859p:plain

f:id:kazuhironagai77:20210307234910p:plain

f:id:kazuhironagai77:20210307234919p:plain

f:id:kazuhironagai77:20210307234927p:plain

f:id:kazuhironagai77:20210307234935p:plain

f:id:kazuhironagai77:20210307234945p:plain

f:id:kazuhironagai77:20210307234955p:plain

f:id:kazuhironagai77:20210307235004p:plain

全ての要素でテストした結果、今までと同じセリフが表示されました。

5.5 Action状態におけるセリフを一括で管理するData Sheet

Comment For Execute Action はCombat UIウィジェット内に作成されたTextタイプの変数です。

調べて見るとEvent Report Begin Execute ActionでPlayerの操作するキャラの場合のみ、それまでComment For Execute Action変数内に足していたセリフをComment Text Content変数に移す事でセリフをCombat UIのコメント欄に表示します。

f:id:kazuhironagai77:20210307235032p:plain

f:id:kazuhironagai77:20210307235039p:plain

f:id:kazuhironagai77:20210307235047p:plain

この変数が管理しているTextも全てData Tableで一括に管理する事にします。

調べたら以下の7か所でのみ使用していました。

f:id:kazuhironagai77:20210307235108p:plain

うーん。思っているより少ないですね。

理由が分かりました。Acition状態でも結構な割合でComment Text Contentが使用されていました。

f:id:kazuhironagai77:20210307235129p:plain

Comment Text Contentに代入されるセリフは全部、Combat Dialogue data tableに移したと思ったんですが、まだ残っていました。これは後で直します。

以下の様にセリフを整理しました。

f:id:kazuhironagai77:20210307235146p:plain

簡単に解説します。

まず(始め)を開きます。

すると以下のような選択肢があります。

f:id:kazuhironagai77:20210307235207p:plain

ここで攻撃を選択したとします。

攻撃のJumpToCommentは1ですので、indexの1にJumpします。

Indexは0から始まるので番号の2がIndexの1に当たります。

f:id:kazuhironagai77:20210307235222p:plain

2の「を攻撃しました{nextline}」を開いて見ます。

f:id:kazuhironagai77:20210307235240p:plain

Answer Choiceに選択がありません。ここで終わりです。

所でAnswerのスペルが間違っていますね。後で直しておきます。

こんな感じでアドベンチャーゲームブックのように全てのセリフが繋がっています。つまりこのData Tableでセリフを一括管理している訳です。

以下に実際の実装を示します。

f:id:kazuhironagai77:20210307235256p:plain

全部載せる意義を感じないので一個だけにします。

テストします。

攻撃、魔法、道具、逃げるのそれぞれの場合で試しましたが特に問題は確認されませんでした。

5.5 Action状態でComment Text Contentに直接追加されるセリフを管理するData Table

Comment Text Content変数に追加すべき残りのセリフを調べると、

  • モンスターのセリフ:1
  • Action時のセリフ:2
  • 戦闘終了後のセリフ:2
  • MPHPの増減に関してのセリフ:4
  • 逃げるを選択した場合に関してのセリフ:2

となって結構バラバラです。

今までのようにこれらのセリフ全てを一つに繋げる事は出来なそうですが、出来るだけ整理します。

f:id:kazuhironagai77:20210307235330p:plain

やっぱり全部のセリフの関係性を繋げるのは不可能ではないですが、今回はパスします。

上二つのData Tableと同じやり方で実装しました。一個だけ例を載せておきます。

f:id:kazuhironagai77:20210307235348p:plain

テストもしました。

Indexで3、番号では4の「は勝利しました。{next line}」は「は勝利しました。{nextline}」が正しかったです。

後、Level Upした時のセリフを忘れていました。

それらを直しました。

5.6 Dialogue System 考察

これで一応、戦闘システムの報連相を担当していた数々のセリフが3つのData Tableにまとめられました。その内2つはそれぞれのセリフの前後関係もはっきり分かりData Tableを見るだけで全体像の把握が出来る仕組みになっています。

最後のData tableはセリフ同士の関係を正しく並べる事が出来なかったので全体像までは分かりません。ただし、今回はやりませんが、これも時間をかけて前の二つのData Tableと組み合わせれば前後関係がはっきり分かる様に作成出来るはずです。

このまとめ方はNPCの対話で発明した方法と全く同じです。

NPCとの対話でも店主との対話だけは教科書で紹介された方法で作成しましたが、勿論、店主との対話も他のNPCと同じ方法で作成する事が出来ます。

つまり、全てのセリフはNPCの対話で作成した形式で書く事が出来るのです。

そしてこのNPCの対話で作成した形式は、一括で全てのセリフを管理出来るだけでなく、セリフの前後関係も会話全体の流れもData Tableを見るだけで理解出来る大変優れた方法です。

NPCの対話で作成した形式を、もっと一般化した言い方をするとアドベンチャーゲームブック形式のまとめ方となります。

これについてはかなり深い考察をする必要があるので「アドベンチャーゲームブック形式によるセリフのまとめ方について」来週考察します。

6.更なるバグだし(1時間はこのゲームで遊ぶ)

先週、10分プレイしただけで大量のバグが見つかってゲームを中断せざるえませんでした。

今週は、1時間はプレイしてバグ出しします。

6.1 兎に角、10分間プレイ

武器屋で武器を買ったら値段が金貨0枚でした。

f:id:kazuhironagai77:20210307235431p:plain

朝になるときにPCが音します。

6.2 モンスターを全部倒す。

2体ほどモンスターを倒した後、隣村の武器屋で最強武器と防具を購入。残りのモンスターはその最強武器で倒した。

所要時間:全部のモンスターを倒すのに、10分程度かかった。

f:id:kazuhironagai77:20210307235452p:plain

見つかったバグ:

  • 勝利のポーズの時に剣が頭に刺さる。
  • モンスターが後ろを向いているとプレイヤーの操作するキャラがすぐ後ろに立っていても気が付かない。

6.3 色々な武器を試す

全部の武器のアニメーションを見てみます。

所要時間:20分程度

見つかったバグ:

弓矢の時、片手剣のモーションになっています。

f:id:kazuhironagai77:20210307235525p:plain

弓と剣のような装備が可能でした。正し、見た目はオカシクない。

f:id:kazuhironagai77:20210307235544p:plain

魔法の杖を装備したら名前が枠からはみ出て表示されました。

f:id:kazuhironagai77:20210307235601p:plain

モーションは両手剣、片手剣、弓、杖など何種類かあった方が良いと思いました。

実際に、以下のアニメーションが提供されているのでそれは可能だと思います。

f:id:kazuhironagai77:20210307235617p:plain

後、結構3D酔いします。1時間プレイしたらきついかもしれません。今週はこれで止めます。

6.4 他に気が付いた事

魔法のeffectが一個しかないのは退屈です。10種類は欲しいです。

7.Levelデザイン

今の所、以下の部分しかありません。

f:id:kazuhironagai77:20210307235655p:plain

因みに作成した地図は以下の様になっています。

f:id:kazuhironagai77:20210307235713p:plain

この地図は結構いい出来ですので、実際のマップも同じに作成するのが良いかもしれません。

ただし、現在ABC、CDEはmap1。JKL、LMNはmap2。そしてYZとXYZはmap3に配置してあります。

この設定は変えたくないです。

ところで、環境でマーケットのフリーを検索すると質の高い完成品があります。

f:id:kazuhironagai77:20210307235731p:plain

これをそのまま使用するのも一つの手であると思います。

普通の箱庭的なゲームのマップのサイズってどれくらいなんでしょうか?

うーん。知らないですね。

やっぱりある程度は自分で作成する事でLevel Designの勉強をすべきですね。

色々考えましたが、このアイデアが一番現実的と思います。

上の地図の海の部分で3分割します。それぞれの陸地を別のマップで作成します。

こんな感じです。

f:id:kazuhironagai77:20210307235749p:plain

ここに今あるmap1、map2、そしてmap3を対応させます。

これで行きましょう。

8.まとめと感想

段々、ジグソーパズルが埋まるような感じでゲームとして成り立つには何をすべきなのかが分かって来ました。

来週は以下の事についてやります。

  • 対話システムとアドベンチャーゲーム本形式によるセリフの整理方法の考察
    • Data Tableを使用する事で、全てのセリフを一括で管理出来る。
    • 全てのセリフの前後関係がData Tableを見るだけで分かる。
  • Game Modeクラスの整理の続き
  • バグの直し
    • 勝利のポーズの時に剣が頭に刺さる。
    • モンスターが後ろを向いているとプレイヤーの操作するキャラがすぐ後ろに立っていても気が付かない。
    • 戦闘時の武器のモーションの追加
    • 魔法の杖を装備したら名前が枠からはみ出て表示されていたのでそれを直す。
    • 魔法のeffectを増やす。
  • Levelデザイン

以上です。

 

 

「Unreal Engine 4.xを使用してRPGを作成する」の足りない部分を作成する 戦闘中のanimation の直し

f:id:kazuhironagai77:20210228233202p:plain

<前文>

他人の評価と

この前文では、日本の話題についてはあんまり書かないと決めています。その理由は、結構な頻度でその問題の当事者にあったりするからです。他人事で批判していたら、その当事者に会ったりした時、かなり気不味いです。ので基本的に日本の話題については書きません。今回だけは例外です。のでかなりボヤカして書きます。

ある人が社会的にかなり権威のある賞を取ったんですが、その時にその人が「俺を今まで馬鹿にしていた連中め。ザマーミロ。」と言ったんです。思わず呟いちゃったんでしょうね。これって社会人としてはかなり問題発言ですし、常識から考えても「今まで応援してくれた人達のお陰でここまで来れました。」位に留めておくべきでした。

しかし、それ聞いた時、私は逆に感動しちゃったんです。だってそんな賞取る人でも、完全無欠でここまで来た訳じゃなくて、そういう世間や上司などの第三者からの理不尽な低評価に、歯を食い縛りながら戦って来た事が分かったからです。彼も天才じゃなかったんです。見えない所で不断の努力を行っていたんですね。しかもずっと評価されない状態で。

何かを成すためには、第三者からの評価は絶対に必要です。自分勝手になったり、そこまで行かなくても客観的な事実に目を向けられずに、間違ったまま進んでしまったりしている時に、他人からの助言ではっと我に返る事が出来るからです。

しかし多くの第三者の人は理不尽としか思えない低評価しか付けない人が多いです。

他人の評価をする義務なんで無いです。実際ほとんどの人は他人の行為や作品に対しての評価はしてくれません。そんな中で評価したり、敢えて助言したりしてくれる人の意見は大変貴重で大切ですし、どんなに理不尽な評価でも本当にその人が思っている事ならば聞かねばなりません。

しかし本当にその人そう思っているんでしょうか?世間一般がそう言うから低評価しておいた。とか、この部下を低評価しておくと自分が上司から高評価受けるから。とか、あるいは、あからさまな悪意によって低評価している場合も多い様に思えます。

そうなった時に、その意見は聞かないと言う選択肢は有りと私は思っています。

しかし世の中の所謂、仕事が出来る人の多くは、そういう人の意見もかなり真剣に聞く傾向にあります。そういう人達は自分に対する戒めが大変強いので、第三者の評価を非常に大切にします。更に「悪意が在ったとしても助言は助言。」と考える人もいます。

それは私の経験から言うと大変危険です。

悪意のある助言や無能な人の評価を聞くのは、第三者の評価を全く聞かない以上に危ないんです。破滅する可能性まで在る最悪の選択です。

言っては何ですが、こういう仕事が出来る人って恵まれた環境で育っていて、本当に悪意がある人や本当に無能な人に今まで会った事が無いんです。厳しい言い方をすると悪意がある人の意見と真剣に助言してくれる人の区別が付かないし、無能な人でも雰囲気だけで有能そうと判断してしまったりします。

私が個人的に見聞した悪意ある助言は「取りあえずここは謝って」と「今日は家に帰ってゆっくり休んで」です。もし謝ったら「次は誠意が足りない。」と更なる譲歩を要求して、最終的には土下座か一筆書かされるまで追い込むそうです。家に帰すのは、貴方が不在の間に貴方に対しての何かしらの犯罪行為を行うためだそうです。

無能な助言で多いのが「数字の間違い」です。これは日本ではあまり無かったですが、アメリカで何回も経験しました。特に役所で。アメリカの恐ろしい所は、嘘には非常に厳しいのに間違いにはほとんどペナルティーが付かないんです。しかし間違いでも損害が発生しますから。損害を受ける側は大変です。

そこまで行っても「実際、悪意が在るのか、自分が意固地になっていて正しい助言に対して悪意があると思い込んでいるのか、自分では分からないじゃないか。」と反論されるかもしれません。

そこで妥協案です。「一回だけその人の助言を聞いて見たらと。」

絶対に無いでしょうが、それで劇的に改善したら聞き続けるべきです。もし変化が無いのなら、破滅する可能性がある意見は無視すべきでしょう。劇的に悪くなったら、その人に対して今すぐ最大級の警戒をすべきです。

最後にまとめると、馬鹿にしていたり低評価しかしない連中は、悪意を持っていたり無能な人の場合が多いですので、評価や助言は無視すべきです。

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

<本文>

1.今週の予定

戦闘中のアニメーションにPlayAnimation nodeを使用していますが、アニメーションは全部AnimBPで管理すべきでした。今週はここを直します。

  • モンスターのAnimBPを改良して、戦闘のAnimationAnimBPで表示出来る様にします。
  • 同様の方法で、Playerが操作するキャラのアニメーションもAnimBPで表示します。

アニメーションを直した後に時間がまだある場合は、このゲームをプレイしてバグ出しをします。

もしバグ出しした後でも、それでも時間があるならば、Levelデザインでもやってマップを完成させます。

2.PlayAnimation ノードを外して、戦闘中のアニメーションもAnimBPで管理する。(モンスターの場合)

2.1 モンスターのAnimBP の復習

AnimBPでどのようにアニメーションを管理しているのかすっかり忘れてしまいました。まず復習から始めます。

MonsterBPを開いて見ると

f:id:kazuhironagai77:20210228233541p:plain

使用しているAnim ClassはSkelSwordAni_Cとなっています。

f:id:kazuhironagai77:20210228233612p:plain

これですね。

f:id:kazuhironagai77:20210228233634p:plain

開いて見ると、まず変数としてSpeedとDelayがありました。

f:id:kazuhironagai77:20210228233707p:plain

以下に示した様に、開始して1.6秒経つとdelay変数がTrueになります。

f:id:kazuhironagai77:20210228233733p:plain

Speed変数はモンスターの移動スピードを表しています。

f:id:kazuhironagai77:20210228233754p:plain

そうだ。思い出して来ました。Animation BPにはEventGraphとAnimGraphがあったんです。

f:id:kazuhironagai77:20210228233813p:plain

今度はAnimGraphを見て行きます。

f:id:kazuhironagai77:20210228233921p:plain

思い出して来ました。このDefaultの中で色々な条件とそれに沿ったアニメーションを指定したんです。

それはそうと、このAnimGraphではDefaultとOutput Pose以上の作成出来るんですかね。もっとUE4アニメーションに詳しくなったらモット複雑な形のAnimGraphがあるんでしょうか?

Default stateの中を見ます。

f:id:kazuhironagai77:20210228233940p:plain

Spawn stateとIdle/Run stateがありその間に条件節が一個あります。

Spawn stateを見るとSkeleton_Swordman_Spawnのanimationを表示させています。

f:id:kazuhironagai77:20210228233958p:plain

Skeleton_Swordman_Spawnのanimationは以下のヤツです。

f:id:kazuhironagai77:20210228234016p:plain

f:id:kazuhironagai77:20210228234024p:plain

f:id:kazuhironagai77:20210228234032p:plain

f:id:kazuhironagai77:20210228234041p:plain

このアニメーションに掛かる時間が1.6秒でした。

もう分かりました。delay変数がTrueになるのが、Spawn stateからIdle/Run stateに移動出来るため条件ですね。

一応調べて見ます。

f:id:kazuhironagai77:20210228234111p:plain

f:id:kazuhironagai77:20210228234121p:plain

その通りでした。

最後のIdle/Runを見ます。

f:id:kazuhironagai77:20210228234303p:plain

あれ。思っていたより簡単な構造でした。

そうか。歩くのと走るのは、早歩きみたいな歩くと走るの中間があるから、それをBlendspace PlayerクラスであるSkelSword1Dで再現したんでした。

SkelSword1Dの中身も見てみます。

f:id:kazuhironagai77:20210228234322p:plain

Speedが345以上で完全に走り出します。Speedが85までは歩いています。

85?

AIでモンスターが探索する時の最大速度は幾つでしたっけ。

MyBehaivorTreeを見てみると150にセットされています。

f:id:kazuhironagai77:20210228234339p:plain

f:id:kazuhironagai77:20210228234347p:plain

計算式を見直さないと数値が同じ単位なのか分かりませんが、後で数値の確認をする必要がありますね。モンスターが探索している時は、歩くべきですので。

取りあえず、モンスターのAnimBPがどうなっているのかは分かりました。

2.2 戦闘時におけるモンスターのplayAnimationの使用箇所についての復習

RPGGameModeBP内の以下の部分でモンスターの戦闘中のアニメーションを担当していました。

f:id:kazuhironagai77:20210228234414p:plain

あれSetViewTargetwithBlendノードは何をする関数何でしょうか?

覚えていません。調べます。

f:id:kazuhironagai77:20210228234430p:plain

使用するカメラを切り替えるんでした。

あれ。でもこの設定だと、カメラを切り替えるだけですよね。

実際の戦闘では以下の様に、モンスターを正面から撮影しています。

f:id:kazuhironagai77:20210228234446p:plain

この設定だとモンスターの後ろ姿を撮影するんじゃ…。

分かりました。

元々、monsterBPのカメラはモンスターに対して正面を向いた状態で作成していました。

f:id:kazuhironagai77:20210228234509p:plain

戦闘中のカメラの管理については全く忘れていました。今週はやりませんが、このやり方が正しいのかの検証は必要ですね。

そしてPlayAnimationです。

f:id:kazuhironagai77:20210228234533p:plain

Skeleton_Swordman_Default_Attackアニメーションをplayしています。

f:id:kazuhironagai77:20210228234557p:plain

この時にSkelSwordAniからこのアニメーションをplay出来るようにすればいい訳ですね。

大体やり方が分かって来ました。

もう一か所、戦闘中のモンスターのアニメーションでPlayeAnimationを使用している箇所がありました。

f:id:kazuhironagai77:20210228234620p:plain

ここでは、モンスターが死んだアニメーションを流しています。

f:id:kazuhironagai77:20210228234636p:plain

これもSkelSwordAniからPlay出来る様にします。

2.3 SkelSwordAniにSkeleton_Swordman_Default_AttackアニメーションとSkeleton_Swordman_Dieアニメーションを追加する。

それでは、モンスターが使用するAnimation BPであるSkelSwordAniからSkeleton_Swordman_Default_AttackアニメーションとSkeleton_Swordman_Dieアニメーションが使用出来るようにします。

SkelSwordAni内に新しいBoolean変数、Attackを作成します。

f:id:kazuhironagai77:20210228234707p:plain

このAttack変数がTrueの時に、Skeleton_Swordman_Default_Attackアニメーションを流すようにします。

まずDefault StateでIdle/Run stateにAttack Stateを追加します。

f:id:kazuhironagai77:20210228234723p:plain

Attack StateではSkeleton_Swordman_Default_Attackアニメーションを流します。

f:id:kazuhironagai77:20210228234740p:plain

移行する条件は、Attack変数の値がTrueに成る事です。

f:id:kazuhironagai77:20210228234757p:plain

これでSkelSwordAniからSkeleton_Swordman_Default_Attackアニメーションが使用出来るはずです。

同様な方法で、Skeleton_Swordman_DieアニメーションもSkelSwordAniから使用出来るようにします。

f:id:kazuhironagai77:20210228234819p:plain

f:id:kazuhironagai77:20210228234825p:plain

f:id:kazuhironagai77:20210228234834p:plain

f:id:kazuhironagai77:20210228234841p:plain

これでSkelSwordAniからSkeleton_Swordman_Dieアニメーションも使用出来るはずです。

2.4 戦闘中にSkelSwordAniからSkeleton_Swordman_Default_Attackアニメーションを使用する。

RPGGameModeBPのここの部分を変更します。

f:id:kazuhironagai77:20210228234907p:plain

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

f:id:kazuhironagai77:20210228234924p:plain

テストします。

普通に攻撃しています。

f:id:kazuhironagai77:20210228234956p:plain

出来ました。

整理して見やすいようにしました。

f:id:kazuhironagai77:20210228235015p:plain

2.5 戦闘中にSkelSwordAniからSkeleton_Swordman_Dieアニメーションを使用する。

今度は、Skeleton_Swordman_Dieアニメーションの番です。Skeleton_Swordman_Default_Attackアニメーションの場合と全く同じやり方で行います。

このPlayAnimationノードを外します。

f:id:kazuhironagai77:20210228235041p:plain

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

f:id:kazuhironagai77:20210228235108p:plain

テストします。

モンスターを倒した時にこのアニメーションが流れましたが、その後で、モンスターが復活してしまいました。

f:id:kazuhironagai77:20210228235128p:plain

良く考えたら当たり前でした。直します。

f:id:kazuhironagai77:20210228235149p:plain

もう一回テストします。

今度は死ぬモーションをひたすら繰り返しています。

うーん。

もうちょっと考えたら直せそうですが、ここはPlayAnimationを使用した方が適切な気がしてきました。

この後、このモンスターがSkelSwordAniを使用して動く事はないからです。

やっぱりここは元に戻します。

f:id:kazuhironagai77:20210228235209p:plain

f:id:kazuhironagai77:20210228235216p:plain

確認のためのテストをします。

f:id:kazuhironagai77:20210228235234p:plain

元に戻りました。

3.PlayAnimation ノードを外して戦闘中のアニメーションもAnimBPで管理する。(プレイヤーの操作するキャラの場合)

プレイヤーの操作するキャラは、素手、武器、魔法を使用した時にそれぞれ別のアニメーションを使用する必要がありますし、特に魔法を使用した時にParticle Systemも使用します。モンスターの時よりかなり複雑なはずです。気を付けてやって行きましょう。

3.1 プレイヤーの操作するキャラのAnimBP の復習

プレイヤーの操作するキャラのためのCharacter Class ですが、ThirdPersonCharacterをそのまま使用していました。

f:id:kazuhironagai77:20210228235305p:plain

使用されているAnim ClassはMyThirdPerson_AnimBP_Cでした。

f:id:kazuhironagai77:20210228235332p:plain

MyThirdPerson_AnimBPを見て行きます。

まず変数ですが、以下の3つがありました。

f:id:kazuhironagai77:20210228235417p:plain

多分、SpeedとIsInAirは元々あった変数と思われます。WithWeaponは自分で追加した事を覚えています。

EventGraphを見てみます。

f:id:kazuhironagai77:20210228235449p:plain

見にくい。ちょっと整理します。

f:id:kazuhironagai77:20210228235508p:plain

EventGraphでは二つの変数の値を常にUpdateし続けていました。

自画自賛ですが、関数の下にその関数にパスする値を書く私のやり方、先週、発明したReroute  nodeを併用すると非常に見やすくなります。これはBPの書き方における大発明かもしれません。最初、この書き方を始めた時は、自分自身ではもっとも分かり易い書き方であると信じていましたが、誰もやっている人がいなくて内心かなり弱気でした。しかしこれを見れば、私の書き方が見やすい、理解しやすいのは一目瞭然です。

整理する前の書き方だと、TryGetPawnOwnerノードを中心に見てしまいます。しかしTryGetPawnOwnerノードからコードの流れを見ても何をやっているのか曖昧になってしまいます。あれっと最初からコードの流れを見る羽目になります。

所が私の書き方だと、まずこの部分の実装の目的は二つの変数、IsiInAirとSpeedに値をセットする事であると一発で分かります。その後でそれらにセットするための値はどうやって得ているのかを知りたくなったら、その下の関数らを追えば良いだけです。

今度はAnimGraphを見てみます。

f:id:kazuhironagai77:20210228235526p:plain

勿論、Default Stateを開きます。

f:id:kazuhironagai77:20210228235543p:plain

成程、分かりました。Idle/RunとIdle/RunWithWeaponのStateがあるんですね。

後、Jumpの機能もあったんですね。

走ったりするStateの中を開いて見る必要がない事は既に分かっているのでここまでにします。

3.2 戦闘時におけるモンスターのplayAnimationの使用箇所についての復習

戦闘時に攻撃を選択した時、武器を所持している時としていない時のアニメーションの表示にPlayAnimationを使用しています。

f:id:kazuhironagai77:20210228235608p:plain

武器を装備しているかどうかはRPGGameInstanceBPから調べるべきでしょう。何で敢えてAnimInstanceから調べているんでしょうか?

以下に示した様に、武器を装備している時はplayAnimationノードの後で、MyThirdPersonAnimBPをセットし直して更にMyThirdPersonAnimBPの変数WithWeaponをTrueに指定しています。

f:id:kazuhironagai77:20210228235627p:plain

本当に無駄手間をかけています。こここそ、全てのアニメーションをMyThirdPersonAnimBPで直接管理すべき所です。

次は魔法を選択した時のアニメーションです。魔法はParticle Systemを使用していますので複雑な構造になっていると思っていたのですが、実際の実装を見るとplayer の操作するキャラとは別なActorがParticle Systemを担当していました。

f:id:kazuhironagai77:20210228235648p:plain

これなら簡単に直せそうです。

更に戦闘に負けて死んだときと戦闘に勝利した時のアニメーションもPlayAnimationが使用されていました。

f:id:kazuhironagai77:20210228235732p:plain

f:id:kazuhironagai77:20210228235742p:plain

これらに使用されているアニメーションは両方とも武器なしのものだけでした。武器在りのアニメーションも追加したら見栄えがもっと良くなると思って提供されているアニメーションを調べたら武器なしのアニメーションしかなかったです。

f:id:kazuhironagai77:20210228235803p:plain

3.3 MyThirdPerson_AnimBPに武器なしの場合の攻撃アニメーションと武器ありの場合の攻撃アニメーション、そして魔法使用時のアニメーションを追加する。

以下の様に追加しました。

f:id:kazuhironagai77:20210228235828p:plain

新たに作成した変数は、MagicとAttackです。

f:id:kazuhironagai77:20210228235847p:plain

Attack変数の使用方法は「2.3 SkelSwordAniにSkeleton_Swordman_Default_AttackアニメーションとSkeleton_Swordman_Dieアニメーションを追加する。」での使用方法と全く同じです。

Magicを使用した場合は武器を装備している時としていない時で返るstateが違います。以下の様に設定しています。

武器装備なしの場合

f:id:kazuhironagai77:20210228235905p:plain

武器装備在りの場合

f:id:kazuhironagai77:20210228235923p:plain

多分これで上手く行くそれぞれのStateに帰るはずです。

戦闘に負けて死ぬアニメーションと戦闘に勝って処理のポーズを取るアニメーションはPlayAnimationを使用する予定なので、これらのアニメーションはMyThirdPerson_AnimBPには追加しません。

3.4 戦闘中にMyThirdPerson_AnimBPから攻撃アニメーションを使用する。

以下の様に攻撃アニメーションの実装を変更しました。MyThirdPerson_AnimBPの実装が正しくされていれば武器装備ありと武器装備なしで分けてアニメーションを指定する必要はないはずです。

f:id:kazuhironagai77:20210301000005p:plain

テストします。

武器を装備したらいきなり攻撃モーションを繰り返し始めました。

調べたら以下の部分を逆に設定していました。

f:id:kazuhironagai77:20210301000046p:plain

もう一度テストします。

武器なしの場合です。

f:id:kazuhironagai77:20210301000159p:plain

武器なしのモーションが選択されています。

武器在りの場合です。

f:id:kazuhironagai77:20210301000230p:plain

武器在りのモーションが流れました。

出来てますね。

コードを整理します。

f:id:kazuhironagai77:20210301000300p:plain

たったこれだけになりました。

3.5 戦闘中にMyThirdPerson_AnimBPから魔法アニメーションを使用する。

今度は魔法アニメーションです。以下の様に実装し直しました。

f:id:kazuhironagai77:20210301000343p:plain

テストします。

何回も同じモーションを繰り返しています。

魔法のモーションが約0.7秒だったので0.7秒辺りでMyThirdPerson_AnimBP のMagic変数の値をFalseに戻しました。

f:id:kazuhironagai77:20210301000403p:plain

テストします。

まず武器なしで魔法を使用した時です。

f:id:kazuhironagai77:20210301000427p:plain

その後、攻撃を選択します。

f:id:kazuhironagai77:20210301000442p:plain

素手の攻撃モーションを使用しています。

今度は武器ありで魔法を使用します。

f:id:kazuhironagai77:20210301000500p:plain

その後、攻撃を選択します。

f:id:kazuhironagai77:20210301000514p:plain

武器の攻撃モーションを使用しています。

出来ていました。

3.6 戦闘中のコードを整理する。

RPGGameModeBP内の戦闘中の実装が以下の様にぐちゃぐちゃなので整理します。

f:id:kazuhironagai77:20210301000535p:plain

以下の様に整理しました。

f:id:kazuhironagai77:20210301000553p:plain

もう少し整理出来ますが、この状態でテストします。

武器在りの時です。

魔法を使用します。

f:id:kazuhironagai77:20210301000619p:plain

その後、攻撃します。

f:id:kazuhironagai77:20210301000636p:plain

武器で攻撃しています。出来ています。

今度のテストは武器なしの時です。

魔法を使用します。

f:id:kazuhironagai77:20210301000705p:plain

その後攻撃します。

f:id:kazuhironagai77:20210301000722p:plain

武器なしの攻撃をしています。

出来ています。

もう少しだけ整理します。

色んな所でMyThirdPerson_AnimBPにアクセスしているので変数として作成します。

f:id:kazuhironagai77:20210301000740p:plain

RPGGameModeBP内のEventBeginPlay関数で、以下に示した様に変数MyThirdPersonAnimBPを作成しました。

f:id:kazuhironagai77:20210301000802p:plain

まだまだスパゲッティコードですが、前よりは遥かに見やすく成りました。

f:id:kazuhironagai77:20210301000819p:plain

確認のテストをします。

スクリーンショットは取らなかったですが出来ている事は確認出来ました。

4.兎に角、Playしてバグを見つける

4.1 Playします。

まず、プレイ中の音楽が無いです。

夜になると真っ暗で何も見えません。

f:id:kazuhironagai77:20210301000846p:plain

PCが突然、凄い音出し始めました。

f:id:kazuhironagai77:20210301000903p:plain

地面の無い所にいったらフリーズしました。

戦闘から戻った時にカメラの方向が一定です。

戦闘中に「読みましたボタン」が表示されないバグが発生しました。

f:id:kazuhironagai77:20210301000919p:plain

再現性もあります。

Level10に成れないためのバグかもしれません。

f:id:kazuhironagai77:20210301000936p:plain

「読みましたボタン」が表示されないバグではなく勝利シーンに移行できないバグのようです。

たった十分程度Playしただけでこれだけのバグが出て来ました。

でもそれなりに面白かったです。

4.2 バグのまとめ

以下のバグが見つかりました。

  • プレイ中の音楽が無い。
  • 夜になると真っ暗で何も見えない。
  • PCが突然、凄い音出し始めました。(ずっとではない。)
  • 地面の無い所にいったらフリーズした。
  • 戦闘から戻った時にカメラの方向が一定。
  • 戦闘から戻れないバグ発生。

これらのバグを直します。

5. バグの直し

5.1 プレイ中の音楽の追加

以下の方法で、Map1にBGMを追加しました。

f:id:kazuhironagai77:20210301001021p:plain

BGMは場所によって変化させる予定なので音の編集が出来るSpawnSound2Dノードを使用します。

使用するCueは以下のデータです

f:id:kazuhironagai77:20210301001042p:plain

Mega Game Music Collectionから使用しました。

f:id:kazuhironagai77:20210301001119p:plain

BGMをループさせるため、Cueを開いてLoopingにチェックします。

f:id:kazuhironagai77:20210301001143p:plain

モンスターが発生する危険な地域や、町や城でBGMは変更しますが、それは後で作成します。

5.2 夜になると真っ暗で何も見えない。

もう単純にPoint LightをThird Person Characterに追加しました。

f:id:kazuhironagai77:20210301001207p:plain

Lightが無い状態です。

f:id:kazuhironagai77:20210301001224p:plain

Lightがある状態です。

f:id:kazuhironagai77:20210301001239p:plain

かなり見やすく成っていますが、回りを見渡すまでは明るくはないです。今回はこれ位にしておきます。

5.3 PCが突然、凄い音出し始めました(ずっとではない)。

再現したくて何回もゲームをPlayしたがその後、一回もそんな事態にはならなかったです。

F5でShaderの負担をチェックしたが特に特別に重そうな所は見つからなかったです。

f:id:kazuhironagai77:20210301001302p:plain

f:id:kazuhironagai77:20210301001310p:plain

原因が不明なのでこのバグの修復はパスします。

5.4 地面の無い所にいったらフリーズした。

落ちたら死ねば良いだけですが、どうやって実装しましょうか?

思い付きました。

この方法はベストではないでしょうが、これでも出来るはずです。

MyThirdPerson_AnimBPに二つの変数、IsInAirとSpeedがあります。

f:id:kazuhironagai77:20210301001337p:plain

更に、ThirdPersonCharacterのMax Walk Speedを見ると600になっています。

f:id:kazuhironagai77:20210301001356p:plain

この二つから推測すると、IsInAirがtrueでSpeedが600以上だった場合、プレイヤーが操作するキャラが墜落していると考えて良いのではないでしょうか?

RPGGameModeBPのTick関数に以下のコードを追加しました。

f:id:kazuhironagai77:20210301001417p:plain

これでPlayerが操作するキャラが墜落した時が分かるはずです。

墜落した場合は墜落死を知らせる新しいmapを開きます。

f:id:kazuhironagai77:20210301001438p:plain

そのためのWidgetも作成しました。

f:id:kazuhironagai77:20210301001456p:plain

テストします。

f:id:kazuhironagai77:20210301001513p:plain

落ちます。

一瞬でGame Overに成りました。

f:id:kazuhironagai77:20210301001536p:plain

もっと発展させる必要はありますが、最低限の機能は出来ました。

5.5 戦闘から戻った時にカメラの方向が一定

これが何で成るのかが分からないです。

考えられるのはRootCompomentとして指定されているCapsuleComponentにScaleしか指定出来ないため指定出来ないのかもしれません。

f:id:kazuhironagai77:20210301002120p:plain

f:id:kazuhironagai77:20210301002128p:plain

色々試したのですが、結局原因は不明でした。

カメラとCameraBoomの関係をもう一度勉強しないと理解出来なそうです。

色々調べたら、PlayerStartの向きとカメラの向きが同じになっているみたいです。

それならPlayerStart を消してPlayerが操作するキャラを動的に作成すれば向きも自然になると思いその方法を調べました。

以下の方法でPlayerが操作するキャラを動的に作成出来るそうです。

f:id:kazuhironagai77:20210301002153p:plain

この方法を試してみます。

以下の方法でMap1、LevelBP内に実装しました。

f:id:kazuhironagai77:20210301002217p:plain

テストします。

f:id:kazuhironagai77:20210301002233p:plain

後ろ向きで戻って来ました。

ただし。大量のエラー報告と一緒にですが…

f:id:kazuhironagai77:20210301002256p:plain

直していきます。

最初のエラーの原因はRPGGameModeBPのMyThirdPersonAnimBPがnullだからでした。その原因はRPGGameModeBPのEventBeginPlayの時にはまだPlayerが操作するキャラを作成していないからです。

Playerが操作するキャラはRPGGameModeBPで作成する事にします。

f:id:kazuhironagai77:20210301002319p:plain

更に戦闘時の場合はPlayerが操作するキャラの生成される場所が違うのでそれに対応した別のSpawnPlayerCharacterBattleFiledも作成します。

f:id:kazuhironagai77:20210301002343p:plain

Levelによってそれぞれのイベントを呼び出します。

f:id:kazuhironagai77:20210301002419p:plain

テストします。

素手の戦闘では上手く行きましたが、武器を持った場合、元に戻った時、以下の様なエラーが発生しました。

f:id:kazuhironagai77:20210301002439p:plain

原因はRPGGameModeBPでPlayerが操作するキャラを作成して更に、Map1でも作成してたからと思われます。

Map1の作成は外します。

f:id:kazuhironagai77:20210301002459p:plain

今度は大丈夫でした。

f:id:kazuhironagai77:20210301002524p:plain

以下のWarningが出ています。何なんでしょうか?

f:id:kazuhironagai77:20210301002649p:plain

分かりませんね。

ThirdPersonCharacterを(0,0,0)の位置にSpawnせよという命令はしていないはずですが。

5.6 戦闘から戻れないバグ発生

レベルが10になった時、以下のif節に入ってエラーになっていました。

f:id:kazuhironagai77:20210301002714p:plain

色々検討した結果、このIf節はrowがNullの全ての場合に対応しているので、消す訳にはいかないので以下のような変更にしました。

f:id:kazuhironagai77:20210301002733p:plain

テストします。
Levelが10に上がってゲームが途中で止まる事も無くなりました。

f:id:kazuhironagai77:20210301002753p:plain

ここは直ったんですが、以下のコードがLevel10になった時にゲームを停止させてしまう事に気が付きました。

f:id:kazuhironagai77:20210301002811p:plain

取りあえず試してみます。

やっぱり停止しました。

f:id:kazuhironagai77:20210301002833p:plain

以下のコードを追加してそもそもLevelが10になった時はLevelUpの検査を受けないようにしました。

f:id:kazuhironagai77:20210301002851p:plain

テストします。

普通に戦闘が終了しました。

直りました。

6.バグ出しもう一回

「5.5 戦闘から戻った時にカメラの方向が一定」でPlayerが操作するキャラをLevel上に配置したPlayerStartから静的に生成するのではなく、動的にBPから生成する事にしました。

この大改造により、バグが大量に生成されていると思われます。

現状把握しているだけでも、以下のWarningは出続けていますし。

f:id:kazuhironagai77:20210301002921p:plain

もう一回バグ出しをやって行きます。

6.1 スタート画面でエラー、更に墜落死画面でもエラー

直します。

以下の様にしました。

f:id:kazuhironagai77:20210301003003p:plain

ここで動的にPlayerの操作するキャラを作成しなければ勝手にPlayerStartの位置にThirdPersonCharacterが作成されるはずです。

試してみます。

出来ました。

出来ましたが、またエラーが大量に発生しました。

f:id:kazuhironagai77:20210301003022p:plain

直します。

ここでエラーが発生しています。

f:id:kazuhironagai77:20210301003040p:plain

成程。このやり方だとMyThirdPersonAnimがnullになってしまうんですね。

直します。

以下の様に直しました。

f:id:kazuhironagai77:20210301003058p:plain

まずEventを止めました。基本的にEventは電話と同じ機能をProgrammingで実装したものです。全ての作業を中止しても対応しなければならない、突然発生する事態(つまり電話の対応)のための機能です。

Playerのキャラを作成する事は突然発生しません。毎回、Levelを開く時にする必要があります。のでEventは使用しません。

代わりに関数、SpawnPlayerCharを作成しました。

f:id:kazuhironagai77:20210301003118p:plain

キャラの生成する位置と角度を指定するとキャラを動的にSpawnしてくれます。

それぞれのLevelや戦闘が発生した場所で、キャラの生成する位置と角度は変わりますので、そこに対応出来る様にします。

f:id:kazuhironagai77:20210301003138p:plain

この部分はもっとマシな書き方があると思います。後で、少し考えます。今回はこれで行きます。

最後に、エラーが出た変数に値をパスします。これでエラー出ないはずです。

f:id:kazuhironagai77:20210301003202p:plain

テストします。

まずスタート画面です。

エラーの表示はありません。出来ています。

f:id:kazuhironagai77:20210301003228p:plain

出来ていますが、何か画面が異常に明るいです。

そうだ。ThirdPersonCharacterにPointLightを追加した事を忘れていました。ここではそのPointLightは切っておくべきですね。

「新しく始める」をクリックしました。

Map1が作成されました。

f:id:kazuhironagai77:20210301003250p:plain

特にエラーの発生はありません。落下してみます。

ゲームオーバーになりました。

f:id:kazuhironagai77:20210301003313p:plain

エラーの表示もないのでバグは直りました。

6.2 スタート画面の修正

スタート画面でPlayerの操作するキャラが明るすぎるのでそれを修正します。

以下の様に直しました。

f:id:kazuhironagai77:20210301003353p:plain

テストします。

f:id:kazuhironagai77:20210301003410p:plain

暗くなっています。

Map1に入ると今度はPlayerの操作するキャラは明るくなっています。

出来ています。

あれ?

Monsterが動いていません。

f:id:kazuhironagai77:20210301003430p:plain

新たなバグの発見です。

6.3 モンスターを動かす

何で動いてないんでしょうか?

AIが機能していないんでしょうか?

Behavior TreeのDebug機能で調べて見ると、Blackboard Decorator ノードであるIsRandomPlace?がFalseを返している事が分かりました。

f:id:kazuhironagai77:20210301003454p:plain

IsRandomPlaceノードの設定を見ると、以下に示した様に、Blackboardの変数、RandomPlaceの値をチェックしています。

f:id:kazuhironagai77:20210301003512p:plain

この値に問題があるみたいです。

BlackboardのRandomPlaceの値は、ServiceクラスであるFindRandomPlace内で指定されています。

FindRandomPlaceを見るとGetRandomReachablePointInRadiusがFalseを返してる事が分かります。

f:id:kazuhironagai77:20210301003531p:plain

更に、GetActorLocationはあるActorの位置情報は返してる事も分かりました。

と言う事は、GetRandomReachablePointInRadiusが適切な場所が見つけられないからモンスターは動いていないと言う事になります。

確認のために他のモンスターの場合も確認しましたが、以下に示した様に全く同じ問題が発生していました。

f:id:kazuhironagai77:20210301003558p:plain

何で、GetRandomReachablePointInRadiuが機能しないのでしょうか?

一番考えられるのは、NavMeshBoundVolumeが機能していない事です。

確認します。

NavMeshBoundVolumeは効いていませんでした。

取りあえず、左側のNavを動かしたらそれだけは効くようになりました。

f:id:kazuhironagai77:20210301003617p:plain

これでテストしてみます。

以下に示すように凄い勢いで追いかけて来ました。

f:id:kazuhironagai77:20210301003634p:plain

直りました。

6.4 以下のWarningについて

今週最後は、以下のWarningについて調べます。

f:id:kazuhironagai77:20210301003654p:plain

Output Logを読み直したらすぐ分かったのですが、これはPlayerStartを消した事から起きるみたいです。

f:id:kazuhironagai77:20210301003710p:plain

となると、直せませんね。もしPlayerStartを追加したら、戦闘マップから戻って来た時に、playerの操作するキャラの向きが一定になってしまいます。

Packagingの時とかに問題にならないと良いですね。

7.来週以降にやらないといけない事

今週中にバグ出しを終えたかったんですが、無理でした。以下に来週以降やらないといけない事をまとめておきます。

  • モンスターの歩く速度の設定がアニメーションとAIで全然違う
  • BGMの変更、町や村、モンスターが居る廃墟で別々のBGMにする。
  • BPの整理。RPGGameModeBPを整理します。
    • そこら中でThirdPersonCharacter変数に値をセットしている。過去、EventBeginPlay関数がBPから呼べなかったので毎回呼び出していた。これを直す。
    • 戦闘システムから呼ばれるEventを整理してまとめる。
  • セリフシステムの整理。確認出来るだけで3種類以上の方法でセリフを管理している。これを統一する。
  • 更なるバグだし。せめて1時間はこのゲームで遊んでバグ出しする。(今週は10分だった。)
  • Levelデザイン。

これらの事をやっていきます。

8.まとめと感想

今週はここまでです。戦闘マップから戻って来た時に、向きが変わってしまう問題は一応解決できました。Levelが10になるとゲームが止まってしまうバグは予想外でした。まだまだ、先は長いですが、ジグソーバズルが埋まって行く時に感じるような手ごたえを感じれるようになって来ました。