<前文>
今週はKyle Rittenhouseについて書こうと思ったんですが、あんまり心の琴線に触れて来ないんです。それで別な話を書く事にします。
先週、ポケモンのような火とか水とかのタイプとHxHの念能力のようなタイプが全く違う事を発見しました。簡単に説明するとポケモンのような火とか水とかのタイプは戦闘が開始する前に勝敗が決する戦略型、HxHの念能力のようなタイプは戦闘中に上手く使用する事で一発逆転が出来る戦術型なんです。
ターン制のRPGの特に魔法に注目して分析すると見事に戦略的な攻撃と戦術的な攻撃に分けられるんです。例えばレベル上げは戦略的です。水タイプで火タイプを攻撃するのも戦略的です。戦闘中に魔法で相手を眠らすのは戦術的です。
戦闘システムにおいて、この戦略的な部分が弱くなるとゲームをしているのが辛くなります。単純なレベル上げなんかやっている意味が無くなるからです。しかし戦略的な部分だけで戦闘が決まってしまうと戦闘中にする事が無くなるので戦闘が楽しくなくなります。バランスが大切になってくるんです。
それでまあ、色々考えたんです。これならレベルを上げたりするのも無駄にならず、戦闘中も色々考える必要がある戦闘システムを。
これだと言うアイデアが何点か出たんです。
その時は、これだと思っていたんですが、後から考えると何かがオカシイ気がして来ました。
それが何なのか分かったんです。確認する手段がないんです。
Programmingならば、コードを書けば一発で正しいか正しくないか確認出来ます。この前のNiagara におけるRibbon Renderingなんかが良い例です。
それぞれのParticleから以下の様なSpriteが作成されそれを繋げてRibbonにしているはずだと予測しましたが、
実際の結果とは合わない部分が出て来ました。
実際は以下の様にParticleの上下と隣のParticleを繋げてRibbonを作成してる様だと変わりました。
予測としてはかなり惜しいとこまで行っていたんですが、最終的な形はかなり変わっています。
この様にprogrammingなら予想に対して検証が出来るんです。
しかし面白い戦闘システムを思いついても検証する方法がないんです。
これが違和感の正体でした。
文型の学問ってそんなもんじゃないの?と思って、寝床で「Unreal Engine 4で極めるゲーム開発」をパラパラ見てたらその事について書かれている箇所があったんです。
面白いゲームのアイデアを思いついても本当にそのゲームが面白いかどうか分からない。だからプロトタイプを作成してそれで遊んでみる。そのプロトタイプですら面白かったら次のステージに進めてみるって。
成程と思いました。
この話を私流に解釈すると、プロトタイプの段階で面白くなるまで工夫するんです。
先程のレベルを上げたりするのも無駄にならず、戦闘中も色々考える必要がある戦闘システムに関しても、もしかしたらUIが見にくくて詰まらないゲームになってしまうかもしれません。あるいはどこかのバランスを調節すると途端に面白くなるとかあるかもしれません。
料理だって塩の量や化学調味料を一寸っとだけ足すだけで凄く美味しくなったりまずくなったりします。
ゲームデザインは、どんなに面白そうでもそれだけでは仮説なんです。本当に面白いかの検証が必要なんです。更に改良したりするための検証も必要なんです。
そのためにプロトタイプを作成してアイデアと現実のズレを確認したり、面白さの検証を行ったりするんです。
成程と思いました。
それでは今週の勉強を始めます。
<本文>
1. 今週の予定
今週は以下の内容をやっていきます。
- Niagara: HLSL Triangle code to UE4 Material nodes Tutorial
- Material : Content Exampleをみる
- NPCのAIを作成するためのAIの復習の続き(Environment Query System)
- Game Design:ポケモン+HxHの念能力 Part 3
- Map1のBug直し
- UE5:naniteの勉強
2.Niagara: HLSL Triangle code to UE4 Material nodes Tutorial[1]を勉強する
CGHOW氏のNiagara: HLSL Triangle code to UE4 Material nodes Tutorial [1]を勉強します。
まず、軽く一回見ました。以下の3つの事をやっています。
- Customノードを使用してHLSLをMaterial内で使用する方法について説明しています。
- HLSLのコードをノードを使用して作成しています。
- ノードを改良して見た目を綺麗にしています。
今週はこのTutorialに沿ってやっていきます。来週、分からない機能について検証します。
2.1 Customノードを使用してHLSLをMaterial内で使用する方法(0.00~10:40位まで)
まず元になるHLSLのCodeをshadertoy.com のTriangle Example [2] からコピーします。
と思ったらCGHOW氏、やっぱりMaterialを先に作るわと言ってMaterialを作成し始めました。
Custom ノードを追加しただけです。
結果です。
何となく、私の方がCGHOW氏のより暗く見えるんですが、目の錯覚でしょう。
設定を見るとFloat3の値が1で返っています。白くなるのが納得出来ます。
厳密に書くと以下の様になります。
最後の値を0に変えます。
黄色になりました。
うーん。もう少しここで遊びたい。色んな事を試してみたい。しかしそれを今週やってしまうと粒度(granularity)が変わってしまうのでそれは来週の検証でやる事にします。
もう一つ重要な事を教えています。
今度は以下の様にCodeを変えます。
MyColorは今思いついた単なる名前です。
そして次にInputsで新しいElementを追加してその名前を先程と同じMyColorとします。
すると以下に示した様にCustomのInputにMyColorが現れます。
これにConstant 3 Vectorノードを繋げると
Constant 3 Vectorの値がCustomノードのMyColor変数にパスされます。
MyColorの型はCode内では宣言していません。HLSLは型を宣言しないで変数の作成が出来るんでしょうか?それとも以下に示した様にOutput TypeでFloat 3を宣言しているからReturn の場合のみ自動でFloat 3になるんでしょうか?
これも来週調べます。
やっとHLSLのコードに戻ります。
Tutorialと同じようにNotpad++にコピーしてHLSLを選択しました。
色が変わらない。
Tutorialはこんなカラフルな色になっています。
多分私のが最新版にUpdateしていないからでしょう。後でUpdateします。
この黄色で塗った部分のコードは要らないそうです。消します。
HLSLを知らないのでMainImage ()関数が何を担当しているのか分かりません。
これも来週調べる事にします。
FragCoordについてですが、これはMaterialのTexCoordと同じだそうです。
座標軸の設定まで同じなのかどうかは分かりません。これは後で調べます。
I ResolutionですがこれはScreenのResolutionだそうです。
I Resolutionの値は1で代替できるそうです。
うーん。何で?これも来週考えます。
次はAtanについてです。
Custom ノードはHLSLなのでAtanをAtan2に変更するそうです。
うん?
今までのコードってHLSLじゃなかったの?
調べたらshadertoy.comはGLSLで書いてあるってありました。
えー。
私が勉強したGLSLとは随分違うんですが。
代替、これだとVertex Shader とFragment Shaderの区別もないじゃないですか?
うーん。分からん。
ただ、先程のFragCoordもFragment ShaderだからFragと言っていたんでしょうか?
WebGLのGLSLとOpenGLのGLSLって全く同じなんでしょうか?
うーん。
分からん。GLSLももう一回勉強しないと分からなくなってしまいましたね。
その辺は後でじっくりとやる事にします。
次にVec2をFloat2に変更します。
後、最後の行のVec4はFloat3に変換しています。
はい。
このコードをCustomノードに移します。
Errorが2つ報告されています。
Tutorialと全く同じ展開です。
これならいけそうですね。
まずFragCoordなんて定義されてねーぞ!と言ってる方から直します。
InputsにfragCoordを追加します。
そして前に教わったようにTexCoord[0]を追加します。
今度は別なErrorが出て来ました。
IResolutionも同様の方法で解決します。
IResolutionにはConstant 2 Vectorを繋げています。
これInputの変数の型は何でも良いみたいですね。
今度はUVが駄目だそうです。
Codeに直接、UVの初期化を追加しました。
Tutorialと同じようにCustom ノードのCode内に追加しましたが、Enterキーに反応してくれません。
行を追加したい時はどうするんでしょうか?
あ
Textの行替えと同じでShift + Enterかもしれませんね。
試してみます。
出来ました。
今度はFragColorがエラーになっています。
FragColorを
Return に変換しました。
今度は良く分からないErrorが表示されています。
Tutorialでも同じErrorが表示されているので安心して先に進む事にします。
はい。
Tutorialでしっかり説明されていました。
簡単にまとめます。
まず以下の部分の実装がErrorを起こしています。
TutorialによればGLSLの場合は以下の様な表現が出来ますが、
HLSLでは
のように書かなければなりません。
うん。
これ見るとHLSLもGLSLも変数や関数はほとんど同じですね。
以下の様に書き変えました。
はい。
こんな結果になりました。
やっぱり三角の向きが逆になっています。TexCoordはFragCoordと同じじゃないです。これは来週追及します。
ここからCodeを改良します。
以下の部分の実装はTexCoordの中心を移動するためのCodeだそうです。
つまりMaterialでいう所の以下の事をしているのと同じだそうです。
うーん。全然意味が分からん。
ここで宣言しているCenterやUVって単なる名前じゃないの?
この辺は後でじっくり勉強し直すとします。
なので以下の様にCodeを簡単にしました。
結果も同じです。
2.2 HLSLのコードをノードを使用して作成する
まずコードが見やすいようにCommentにコードを写します。
Comment Colorを黒にするとBackground Colorが黒くなって見やすいです。
先程作成したUVの部分はそのまま使用します。
この部分です。
次のLineです。
当然これだけです。
Piの値を先にやります。
Piと2Piです。
2Piの値をDebug Scalar Valuesノードで確認します。
合ってますね。
以下の実装部をノードで作成します。
こんな感じになります。
Materialは変数がないのでノードに直接、この変数の値はこのノードです。と書き込まないと訳分からなくなります。
因みにaの見た目はこんな感じです。
次はRを作成します。
そのままです。
dです。
DのCodeです。
TutorialではDのPreviewが以下の様になって
HLSLのDの結果の
と一致しません。その理由がCosineの計算結果が違うからです。
それを直すのにこのTutorialでは新しいcustom nodeを作成して
以下のCodeを追加して
としてこのCustom Nodeを使用してCosineノードを外しています。
しかしそんな事をしなくても
Cosineノードの
Periodの値を6.28に変更すれば
同じ結果になります。
うおおォオー。Ben Cloward先生!
先生のSine and Cosine - Shader Graph Basics - Episode 19 [3] のおかげでUEのCosineのTrapに引っかからなかったです。
しかしCGHOW氏程の人でもこのUEのSine、CosineのTrapに引っかかるんですね。
最後の部分です。
以下の様に実装します。
結果です。
2.3 ノードを改良して見た目を綺麗にする
Materialのノードの方をResult ノードに繋げます。
こんな感じです。
三角の数を増やします。
結果です。
うん。Wrappingになってない。
Fracを追加したら
なりました。
Fracノードに関しては来週検証します。
今度は三角を回転させます。
Custom Rotatorノードを使用します。
このノードの詳細については来週検討しますが、Rotation Centerにパスする値が(‐0.5、‐0.5)じゃなくて(0.5、0.5)なんですね。
結果です。
今度はそれぞれの三角の回転をバラバラにします。
Perlin NoiseのTextureです。
これに以下の実装を繋ぎます。
Constant の4はさっきまでは5でした。
その結果です。
何でこんな結果になるのか不明です。
これも来週検討します。
これを先程のCustom RotatorノードRotation Angleに接続します。
こんな感じです。
今度は時間で回転させます。
以下の実装を追加してCustom RotatorノードRotation Angleに接続します。
結果です。
SineのPeriodに6.28を入れるとTimeに1を掛けても(つまり何もしなくても)上記のようなゆっくりした回転でした。
最後にそれぞれの三角に色を付けます。
まずは以下のコードを追加して白を赤色にします。
こんな感じです。
更にHue Shiftノードを追加して
Hue Shift Percentage(s) Resultノードに先程の三角を時間で回転させる実装を繋げます。
Hue Shift Percentage(s) Resultノードについては来週、検証します。
すると
の様に時間で三角形の色が変わるようになりました。
ただしこれを撮影したら以下の様に点々が画面一杯に表示されるようになってしまいました。
勿論、普通に画面を見ているだけではこんな点々は全く見えません。これは録画の方の問題なのかもしれませんが実際はよく分かりませんね。
以上です。
と思ったらもう少しだけありました。
今度はギラギラに光らせます。
以下の赤線で囲っているコードを追加します。
Multiplyノードの先には
があります。
結果です。
ギラギラに光っています。
理屈は大体分かりますが、念のために数字をグラフ化して厳密に一つ一つのノードで何が起きているのかを来週やります。
先程の実装にSaturateノードを足すと
以下の様に三角が消えたりします。
大変綺麗です。
これも理屈は分かりますが、念のために数字をグラフ化して厳密に一つ一つのノードで何が起きているのかを来週やります。
これでお終いでした。
3.Material : Content Exampleをみる
3.1 Material Propertiesの続きをやる
<two Sided>
公式のDocumentである1.4 - Two Sided [4] を見てみます。
短い。
半透明なMaterialだったらTwo Sidedの方が誇張された表現になると言っています。それだけです。
実際の展示を見るとTwo Sidedの方が内側のLineがはっきり見えますね。ただそれが誇張されているとは感じません。
単にもっと正確な描写をしていると感じます。
後Two sidedは草の陰の問題について論じて欲しかったです。
<1.5 - Material Domain>
これは何の説明をしているんでしょうか?
公式のDocumentである1.5 - Material Domain [5] を読んでいきます。
今知ったんですが、
を選択してFを押すと公式のDocumentに飛んでくれるんですね。
このQuestion markはDocumentation Actorと言うそうです。
Documentation ActorのDetailにある以下のボタンをクリックしても公式のDocumentに飛びますね。
その下にあるDocument Linkで飛ぶサイトのAddressを指定しているんですね。
これの説明でした。
ただしここではMaterial Domainではこんな種類があります。という感じでそれぞれの作成方法とか使い方についての解説はありませんでした。
観光レベルの確認と言った感じです。
展示されてるのはSurface、Deferred Decal、Light Function、そしてPost Processの4つです。VolumeとUser Interfaceの展示はないです。
Light Functionは多分初めて見ました。
<1.6 Separate Translucency>
これは何やってるのか不明ですね。
公式のDocumentである1.6 - Separate Translucency [6] を見ると
こんな感じに見えるらしいんですが、幾らやっても見えないです。
博物館に行くと展示物の内で一個や2個は幾らボタン押してもウンともスンとも言わないヤツがあるじゃないですか。あんな感じです。
全く意味不明なので次に行きます。
<Volumetric Directional Lighting Intensity>
まずびっくりなのが公式のdocumentである1.7 - Volumetric Directional Lighting Intensity が何一つ説明してない事です。
この記事書いたヤツ首にしろよ。ホントに。
仕方ないので0.5の展示物のMaterialを開いてTranslucencyの箇所を開きました。
やっぱりここの値を変化させていたんですね。
Light ModeがVolumetric Directionalにセットされた場合、DefaultであるVolumetric Non Directionalの一番の違いはNormalの値を考慮する事であると先週習いました。
であるから、Directional Lighting Intensityの値によってNormalから作成される陰がどう変化するかがこの展示の肝なはずです。
うん。
このモデル達、表面がツルツルでNormalの影響が全く分かりません。
MaterialにNormalが使用されてすらないです。
うん。
私が勘違いしてるの?
本来ならここで自分でNormalの値を持つTranslucentのMaterialを作って白黒はっきりつけるのですが、粒度(Granularity)をそろえるのが大切と言ったので今回はやりません。が来週やります。
次に行きます。
<Tessellation>
PN Triangleって膨らましているんですね。
衝撃です。
これ見ると一発でFlat Tessellationとの違いが分かります。
1.8 – Tessellation [7] にはPN TriangleはObjectを滑らかにするとあります。
一応Materialの設定している箇所の確認もします。
<Opacity Mask Clip Value>
これはやってる事はすぐに分かりました。
黒から白に徐々に変化している箇所のどの程度まで黒とみなして透明にするかを示しています。0.01なら黒の部分しか透明になりません。0.33だとやや黒い部分も透明になります。0.8だとほとんど透明になります。
しかしどこでこの設定をしているのかが不明です。
調べます。
Materialにありました。名前はそのものずばりOpacity Mask Clip Valueでした。
1.9 - Opacity Mask Clip Value [8] も見てみます。
大体推測した通りの説明がされています。
得する豆知識としてMipmapが効くような遠くに配置されている状態だとこの効果は無くなる事が説明されていました。
<Cast Translucent Shadow as Masked>
Maskedしたヤツに影を追加するんですね。
と思ったらBlend ModeがMaskedじゃなくてTranslucentでした。
1.10 - Cast Translucent Shadow as Masked [9] によるとTranslucent では影は作成出来ないそうです。しかしMaskedとして扱う事で影を作成する事が出来るそうです。ただしこの影はLight Massを使用して作成しているので動的な影を作成する事は出来ないそうです。
実際の設定はLight Massにありました。
<Refraction Depth Bias>
これは何をやってるのか全く分かりません。
Refraction Depth Biasの値が⒖の方は鏡に映っていませんね。それの事を指しているのでしょうか?
1.11 - Refraction Depth Bias [10] によると鏡に近すぎるObjectをMaskする機能だそうです。
ふーん。です。
やっぱり鏡に反射して写っている絵の作成はコストがかかるんでしょうか?それとも別な理由で鏡に写るObjectを消したい時があるんでしょうか?
何と、この設定、鏡の方でしてました。
鏡のMaterialの作成方法を知らないのでこの辺は後で勉強する事にします。
以上です。
3.2 Shader Performance Measurement Part 2 [10] を勉強する
Ben Cloward氏の Shader Performance Measurement Part 2 [10]を勉強します。先週のpart 1が神回だったのでPart2も期待してしまいます。
まずサラッと見ました。
今回は、前回からの続きです。前回はMaterialに表示されているInstructionの数は本当の計算costとは関係ない事を3つの点から証明しました。
今回は、どうやったらMaterialの本当の計算Costが測定出来るのかについて実演しています。
最初の方法はPackagingをして実際の製品と同じ状態にしてFrame Rateを測定します。説明を聞いていると結構細かい設定を弄る必要がありそうです。UE5とUnityそれぞれのやり方を解説していました。UE5のPackagingに関しては特別な手順が更に必要らしくそれは別なSiteで勉強して下さい。と言っていました。
その後でPIXを使用して正確なCostを測定する方法が紹介されていました。PIXに関しては今回実際に試してみるかちょっと躊躇しています。
PIXで測定するためにはWidowsとNvidiaの設定をDeveloper Modeに変更しないと起動しないみたいな事を言っていました。しかしそれをすると他の部分にどんな影響が出るのか不明なのでその辺を理解した上で試したいです。
うーん。結構大変そうですね。
出来る範囲でやる事にします。
<Packaging を利用したMaterialのCostの測定方法-UE5編>
以下の3つのStepで作成します。
- Materialと最低のLightingのみLevelを作成しPackage化する。
- 対象のHardware上で1で作成したアプリを実行する
- Toolを使用してそのMaterialがRenderingされるまでに必要なコストを実際に測定する
とありました。
さっき見た時は、2と3は別な方法だと思ったんですがこの説明だと2でFPSを表示したのはあくまでも参考値と言う事みたいです。
それではTutorialの通りに作成していきます。
<<1. Materialと最低のLightingのみLevelを作成しPackage化する>>
まず空のLevelを作成します。
Planeを原点に追加します。
次にDirectional Lightを追加します。
Rotationの値はTutorialと同じにしました。
特にこの値でないといけないと言う事はなさそうです。
Cameraを追加します。
カメラから見た映像がPlaneのみが写っている様にします。
Cameraの位置の設定は以下の様にしました。
Planeに測定するMaterialを追加します。
Tutorialのような水飛沫が飛んでるMaterialはないのでM_Wood_Oakを使用しました。
後、あんまり関係ないですがTutorialでMeasure the performance of the materialと言っています。日本語だとMaterialを測定すると言う方がしっくりしますが、英語だとMaterialのパフォーマンスを測定すると言う方が正しいみたいですね。
これでUE5側の設定は完成だそうです。他のMaterialの測定をしたい時はこのLevelのMaterialだけを変更すれば良いそうです。
今度はこのLevelを対象のHardware上で動かすためのPackagingをやっていきます。
はい。ここでUE5でPackagingをするための特別な設定をする必要があります。
うーん。どうしようかな?
このPCでUE5は完全には動かないんで、UE5のPackagingのための設定をするのは新しいPCを買ってUE5を本格的に起動させる時でも良い気がしています。実はUE4.25 以降のAndroidのPackagingもしていません。面倒くさくて。
一応、やり方だけ確認しておきます。
TutorialによるとAre you unable to package Windows projects in UE5? Fear not, I have a solution for you! [11] にUE5のPackagingが出来るようにするためのやり方がまとめられているそうです。見てみましょう。
やらないですけど場所だけ確認しておきます。
こいつの事でしょうね。
これをここにCopyすれば良いそうです。
次は
だそうです。
いや.NET Core 3.1 Runtimeは既にInstallしてるはず。
と思ったら自分が入れているのは.NET Frameworkの方でした。どう違うのか調べたらウラァァァーと大量のサイトが出て来たので後で読まさせてもらいます。
うーん。Visual Studio CodeはInstallしているのでVersionは兎も角、.NET Coreは入ってそうですが見つからないですね。
CoreとFrameworkの機能を見てるとFrameworkでも出来そうですがどうなんでしょうか?
うーん。これはUE5を本格的に起動する時に試す事にします。
これで終だそうです。
コメント欄を見たら、全部やったけどPackaging出来ません。の嵐です。
うん。多分これだけだと出来ないみたいですね。
UE5の正式Releaseまで待った方が良いみたいです。
後は、Project Setting のMap and ModeにこのLevelをセットするのを忘れない事とか、まあ当然の事だけ言っています。
これでPackagingをPlatformsから
選択するそうです。
ここにSDKがないよって書かれていますね。
SDKが入っていればいいの。それなら…。いや止めておきます。
この後Packageで作成したexe fileを開いてFrame Rateを測っています。
更にFrame RateはIn Gameで測った方が良いそうでそのための方法を外部リンクで紹介しています。
そのやり方は
だけでした。
多分使用しませんが一応UE4でPackagingをしたMaterialを作成しました。
指定したCameraとは別なCameraが使用されるのでCameraの指定をLevel BPでしたりCursorは表示されていた方がGame 以外の事をするのが楽なので追加したりしました。
Exe fileから開いて見ます。
何これ?
でこれになりました。
これはひょっとして私のVideo CardのDriverが古いから起きているのでしょうか?
直りました。
Planeとカメラの位置を一寸ずらしたら消えました。
Frame Rateも出ています。
初期のTemplate の設定だったみたいです。
<<Toolを使用してそのMaterialがRenderingされるまでに必要なコストを実際に測定する>>
PixをInstallしようとしたんですが、Errorが出てInstall出来ませんでした。よく見たらPixはWindows10専用って書かれています。私のPCじゃ動かないです。
なのでここからはやり方だけ見て終りにします。
ここに調べるExe fileを入れるそうです。
後Exe.はDeveloper modeで作成したヤツじゃないと駄目だそうです。
全部見たのですが、これはPixをInstallした後でやらないと分からないですね。残念ですがここは今週は諦めます。
以上です。
4.NPCのAIを作成するためのAIの復習の続き(Environment Query System)
今週はEnvironment Query System Quick Start [12] をもう一回やり直します。先週2021-02-07のblogを読み直しましたがEnvironment Query System Quick Start [12]を勉強してかなりEQSの使用方法を理解していました。
2021-02-07のblogは以下の仮説に基づいて勉強しています。
ただし以下の質問にたいしての解答をまとめている箇所がないです。
ので今、2021-02-07のblogから読み直してまとめると
グリッドの作成方法に関してはEnvironment Queryから派生して作成したEQS_FindPlayer内のBPでSimpleGrid: generate around Querierノードを作成する事で出来るそうです。
残りは分かりませんね。
とりあえずもう一回、Environment Query System Quick Start [12]をやり直しながら色々な疑問を解消していきましょう。
4.1 Environment Query System Quick Start [12]を勉強する
4.27のDocumentでもまだExperimentと書かれていますね。
EQSが標準装備されているのでもうExperimentではないはず。と書かれています。
念のために4.27で調べて見ましたがEQSは標準装備されていました。
このTutorialは4.27のDocumentに書かれているので古いのが直ってなかったと言う事はないはずです。
うーん。
<1 - Required Project Setup>
4.27のEditor PreferencesのExperimentalを開くとAIの項目はありません。
と言う事は公式のDocumentであるEnvironment Query System Quick Start [12]の記述が間違っていると言う事です。
よく公式のDocumentを読めよ。と威圧的に言う輩がいますが、こうやってしっかり公式のDocumentを読んでいると公式のDocumentもそんなに真剣に書かれていない事が分かります。公式のDocumentを読めよ。と言う輩は自分が公式のDocumentを読んでいない事をそう言って露呈しているだけと言う事が分かりますね。
以下のクラスを作成しました。
UE4のAIでお馴染みのAI Controllerクラス、Characterクラス、Blackboardクラス、そしてBehavior Treeクラスが作成されています。その上でEQSのためにEnvironment QueryクラスとEnvQuery Context Blueprint Baseクラスが作成されています。
2021-02-07のblogでも同じ事を言っています。
Environment QueryクラスとEnvQuery Context Blueprint Baseクラスの役割についてまとめるのもやってなかったですね。これもやります。
<2 - Environment Query Context>
と書かれています。
ここでのContextの意味が分かりますか?前後関係とか文脈とかに訳すと意味が全く通じませんよね。ほとんどの英和辞典にはこの訳は書かれていませんが、ここでは条件と言う意味になります。HxHでの制約と誓約の制約の部分と一緒です。Player CharacterのEQS Systemにある制約を付けますと言う意味です。
EQC_PlayerContextのBPを開いてProvide Single Actor関数を以下に示したようにOverrideします。
EQC_PlayerContextにSingle ActorをProvideしろと命令するとPlayer Characterを返す様にしました。
これだけではまだEQC_PlayerContext、つまりEnvQuery Context Blueprint Baseクラスの役割と機能は分かりませんが、その一端は既に目撃出来た訳です。
<3 - EQS Setup>
ここから本格的になります。
Environmental Queryクラスから作成したEQS_FindPlayerクラスのBPに、Player の操作するキャラが見える位置を見つけるためのTestを実装します。
2021-02-07のblogでもこの章は他の章の何倍の書き込みがされています。これも読みながら実装する事にします。
まず、Simple Gridノードを追加します。
2021-02-07のblogではこのノードの機能について色々言っていますが一端、離れてTutorialの解説を読んでみます。
Tutorialの解説で言うItemは以下に示した一つ一つの球を指していると考えられます。
つまり、私が言っているGridの事を指しています。
これらのItem、一個一個がEnvironmental Queryクラスで指定したテストを行い、それぞれの点数を保持します。その中から最高点、もしくは最低点を持つItemが次の移動場所として選ばれると言う訳です。
Simple Gridノードの以下の項目の値を変更しました。
Simple Gridノードが半径と言っているのでGrid Half SizeがItemを生成する半径のサイズ、Space BetweenがそれぞれのItemを配置する時の隙間を指定しているはずです。
ただ前にやったEQSを見ると四角形になってますね。その辺はよく分からないです。
TutorialにはGenerate Aroundについての解説もあります。
これTutorialは色々説明していますが、結局はGridを発生させる位置をこれで決めています。上記の設定ならQuerierの周りにGrid、つまりItemが発生します。
QuerierがAIを指しているのか、先程、EQC_PlayerContextで指定したPlayer Characterを指しているのかは今の時点では不明です。
次はProjection Dataについてです。
Gridの生成についてのもっと細かい指定をする箇所です。通常はDefaultで問題ないはずです。
Simple Gridを右クリックしてTest、Traceを追加します。
Querierが見えるのか聞いているんでしょうか?
となるとQuerierって探索する相手の事になるの?
ちょっと分からなくなっていきました。この部分だけは。後でしっかり検討しましょう。
更にDistanceを追加します。
もしQuerierが見えたらその距離を測りましょうと言う事でしょうね。
Traceの設定を以下の様に変更しました。
はい。
Text PurposeはFilter Only。つまり見えるか見えないかです。
Contextは誰を見るのかを指定しています。ここに先程、EnvQuery Content Blueprint Baseクラスから作成したEQC_PlayerContextを指定しています。つまりこれで見る対象を指定しています。
先程、Querierが見えるのか聞いているようにも読めると言いましたがそれが完全な間違いである事もここから分かりました。
最後のBool Matchが何を指しているのかだけは分かりません。MatchしたつまりPlayerが操作するキャラが見えるItemを返すのがBool MatchがTrueだとしっくりくるのですが、実際はFalseにしています。Tutorialの説明を読むとFalseにセットするとPlayerが操作するキャラが見えないItemは全部消去されるとありますので、私の直観と逆の設定でした。
今度はDistanceの設定を変更します。
当然、Playerの操作するキャラとの距離によって最適なItemを選択するのでTest PurposeはScore Onlyになります。最も近い距離のItemが選ばれるためにはScoring Factorに-1を掛ける必要があります。
それだけです。
<<最初の疑問に対する解答>>
この4つの疑問に対して既に3つがここまでの勉強で判明しましたね。
まず最初の疑問である「グリッドの作成方法」については既に述べていますが、Environmental Queryクラスから作成したEQS_FindPlayerクラスのBP内にSimple Gridノードを追加する事で作成しています。
次の質問である「そのグリッドに対してどうやって値を付けるのか?」に対する解答は以下に示した様に先程使用したSimple GridノードのAdd Testを使用する事で望みの値を測定してその値をそれぞれのItemに付加します。
三番目の質問は「重みの計算方法」ですがこれは先程のAdd Testの指定方法によって完全に自由ではないですがほぼ自由に決定する事が出来ます。
四番目の質問は「できた重みと値をどう利用するのか。」です。
???
あ、勘違いしてました。
この場合の値とはItemが持つ値でItem間の値をInterpolateする時にどの程度周りのItemの値を考慮してその値を計算するのかを重みとして表現していました。EQSでは多分ですが重みの概念はないですね。Item間のInterpolateを求める事自体がないですから。
となると最初の4つの疑問は既に解決しましたね。
<<2021-02-07のblogの3 - EQS Setupについて>>
2021-02-07のblogの3 - EQS Setupが結構、濃い内容が書かれています。これを読み直して今、忘れている事や逆に今なら分かる事などをまとめておきます。
Simple GridノードのProjection Dataについての疑問ですね。
これは上の方で既に判明しています。
これが解答ですね。
残りの疑問も既に上で判明している事ですね。同じ事を2回書くのもあれなんでこれはパスして次に行きます。
<4 - Blackboard and Behavior Tree Setup>
Blackboardに以下の変数を追加しました。
Behavior Treeは以下の様に作成しました。
これは通常のAIの作成でEQSとは関係ないですね。
次に行きます。
<5 - Behavior Tree: Patrol Setup>
ここでは新しいTaskであるBTT_Random Locationを作成しました。
Tutorialの間違いですが、Blackboard Keyの名前が説明文ではMove to Locationになっていますが、図だとPatrol Locationになっています。
作成したTaskをBehavior Treeに追加します。
BTT_Random Locationの変数であるBlackboard Key型の変数であるMove to LocationにBlackboardクラスの変数Move to Locationをセットします。
これも通常のUE4のAIの作成の一環でEQSはまだ出て来ていませんね。
<6 - Behavior Tree: In Combat Setup>
ここでEQSをBehavior Treeから呼ぶ方法が明らかになりました。
Task Run EQS Queryを使用します。
設定は以下の様にします。
まずQuery TemplateにEnvironment Queryから先程作成したEQS_FindPlayerをセットします。更にBlackboard KeyにMove to Locationをセットします。これでBlackboard の変数であるMove to LocationにEQS_FindPlayerの返し値がセットされます。
ここでは更にRotate to face BB entryを使用しています。
このTaskは後でMonsterに追加しようと思っていたやつです。
<7 - AI Controller Setup>
特にEQSには関係ない設定なのでスキップします。
<8 - Final Setup>
一応完成させました。
<9 - End Result>
私を見つけても私を見ませんし追いかけても来ません。
直します。
簡単には直りませんでした。これは来週Debugを使用して直します。
5.Game Design:ポケモン+HxHの念能力 Part 3
先週、戦闘が開始する前に勝敗が決してしまうポケモンなどの火とか水などのタイプ別な要素などを戦略的要素に、戦闘中でも逆転出来るHxHの念能力な戦術的要素を追加する事で戦闘そのものが面白いRPGのシステムを考えました。考えたのは良いんですがProgrammingとは違い、本当にそれが面白いのかどうかの検証ができません。
そしたら前文に書いたのですが「Unreal Engine 4で極めるゲーム開発」に面白いゲームのアイデアを思いついても本当にそのゲームが面白いかどうか分からない。だからプロトタイプを作成してそれで遊んでみる。そのプロトタイプですら面白かったら次のステージに進めてみるって書かれていました。
プロトタイプを作成してみます。
更に今作成しているRPGの戦闘は一種類のMonsterが同じ攻撃を繰り返すだけなので戦闘が退屈です。これを改善したいです。うーん。でもこれは一回完成させる方が大切かもしれません。
今週は今作成しているRPGの戦闘を面白くするためにはどうしたら良いかについて考えます。
まず戦略的要素を増やすためにMonsterの種類は増やす必要があります。現状の一種類のMonsterだけでは戦闘が退屈になります。
第二に同じMonsterでも複数の選択が出来るようにします。その選択は戦術的要素を追加するものであるべきです。例えば体力が減ったら回復をするとか、相手を眠らせるとか、攻撃力を上げるとかです。
うーん。
あんまりピンと来ません。
思い付きました。Monsterの大きさをちょっと変えるんです。大きさによって戦闘力もちょっとだけ変化します。身長が攻撃力、横幅が防御力に関係する事にします。これで一回一回の戦闘が一寸だけ面白くなります。
6.Map1のBug直し
6.1 Warp後の3秒間
3秒間だけEffectを表示します。
以下の実装で試してみます。
RPG Game Mode BPのEvent BeginPlayの最後に追加しています。
結果です。
音を追加したりキャラを半透明や部分だけ透明にしたりすればもっと良くなりそうですがこれでも十分凄いです。
6.2 井戸に(!!)をつける
これ簡単に言っていましたが全ての配置されている建造物につけると大変でした。
それは(!!)の仕組みを全部バラバラで作成してしまったからです。
UE4 RPGGameModeBaseに作成したEnumクラス
ThirdPersonCharacter内で使用される時
これを作成した時はこんなに複雑になるとは思っていませんでした。
今だったらこんなデザインパターンは採用しませんが、当時はどのくらい複雑になるのか分からなかったのでどんどん足していってしまいました。
Itemや武器を拾うためのPE_PickUpは一個で全てのItemや武器に対応しています。NPCは全部バラバラです。
これはどうやって直すのかもしくは単に足すのかを今週一杯考える事にします。
6.3 店の看板を直す
店の看板が英語のままなので直します。
何と日本語の表示が出来ません。そう言えば昔、日本語の表示をするためには何かしないといけないと言う記事を読んだ気がします。
一応RPGは中世のヨーロッパ風な作りになるので日本語がバーンと表示されるのも変な気もして来ました。
絵か看板を表示させるか、いっその事このままでも良い気もしています。
これもちょっと考えます。
6.4 VFXの表示
以下に示したEffectはPlayerが操作するキャラが近づいた時だけ点火すれば良いです。
直します。
近づくと火がつきます。
実装は以下の通りです。
6.5 Warp機能について
これは後で考えます。Landscape4の後の話になると思います。
今週はこのMapによるWarp機能をどうやって物語に繋げていくかを考えます。
今考えているのは、それぞれのLandscapeに銀河鉄道で行ける様になった後でMapが使用出来るようになる。ですがそれだとお話が単純すぎるかもしれません。
MapはLandscape4の冒険が終わったら使用出来るようにして、ただしMapで移動出来る場所は銀河鉄道で移動する同じ場所の1000年後の世界とかにしたら話が広がるかもしれません。
千年後の世界は荒廃していてもう滅ぶ寸前なんです。
その村の人達が1000年前にある事件が起きてその時、選択を間違ったからこんな事態になったと。言います。
そして元の世界で物語を進めていくとその事件が起きると言うわけです。
勿論、Playerは地図を使ってワープすると1000年後の世界に移動している事はそれまでは知らない訳ですが、事件が起きる事であれ、と気が付く訳です。
そしてPlayerが破滅の未来を変えるためにその事件に関わる訳です。
となるとこの地図の機能を使用するために新しい切符が必要にすれば良いんです。
その切符が手に入るのがLandsape4の章の後だったら良い訳です。
この機能を直す時は、一回全部この機能の仕組みを復習する必要があります。ので結構大掛かりになります。
やるにしても来週以降ですね。
6.6 戦闘画面への移行の時のLoad画面の表示について
今のLoading ScreenはAsync Loading Screenを使用して作成しています。
この解説であるAsync Loading ScreenのDocument [13] を読む限りでは
この値はBP側からでは変更出来ないみたいです。Minimum Loading Screen Display Timeは-1に戻しました。
流石に-1だと変です。
2にしてみます。
2秒位なら戦闘画面への移行は気にならないです。
ただしこの変更だと銀河鉄道に乗った時も2秒のままになってしまいます。
銀河鉄道に乗った時は最低でも5秒間位のLoading Screenの表示がほしいですね。
うーん。
この辺を改良するためには、Async Loading ScreenのDocument [13]のコードを読んで改良する以外に方法はなさそうですね。
6.7 Load画面とLoad中に表示されている文章をもっと多くする
これもRPGの物語が決まれば沢山の話が追加出来ます。
後、Monsterについてとか、ItemについてとかのTipも追加出来ます。
墜落死した時用のLoading Screenは今作成してみます。
こんな感じで作成しました。
今週はここで時間が無くなってしまったので中止します。残りは来週やります。
7.UE5:Naniteの勉強
これも来週やります。
8.感想とまとめ
今週は別な用事が出来てしまい、時間と集中力の確保が出来ませんでした。しかしGame Designに関しては形が見えて来ました。上手く進捗しない時でも何かしらは進歩が見られます。諦めずに続けていくのが大切と思います。
9.参照(Reference)
[1] CGHOW. (2021, November 22). HLSL Triangle code to UE4 Material nodes Tutorial | Download Files [Video]. YouTube. https://www.youtube.com/watch?v=JUnjDu33Nq8
[2] Heavybrush, H. (n.d.). Shadertoy. Shadertoy. Retrieved December 5, 2021, from https://www.shadertoy.com/view/MlySzw
[3] Cloward, B. [Ben Cloward]. (2021a, October 21). Sine and Cosine - Shader Graph Basics - Episode 19 [Video]. YouTube. https://www.youtube.com/watch?v=IFyZNSyjyFA&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=19
[4] Epic Games. (n.d.-a). 1.4 - Two Sided. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MaterialProperties/1_4/
[5] Epic Games. (n.d.-b). 1.5 - Material Domain. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MaterialProperties/1_5/
[6] Epic Games. (n.d.-c). 1.6 - Separate Translucency. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MaterialProperties/1_6/
[7] Epic Games. (n.d.-d). 1.8 - Tessellation. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MaterialProperties/1_8/
[8] Epic Games. (n.d.-e). 1.9 - Opacity Mask Clip Value. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MaterialProperties/1_9/
[9] Epic Games. (n.d.-f). 1.10 - Cast Translucent Shadow as Masked. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/MaterialProperties/1_10/
[10] Cloward, B. [Ben Cloward]. (2021b, November 11). Shader Performance Measurement Part 2 - Shader Graph Basics - Episode 22 [Video]. YouTube. https://www.youtube.com/watch?v=iQLBbcqNv2E&list=PL78XDi0TS4lEBWa2Hpzg2SRC5njCcKydl&index=22
[11] Schytheron. (n.d.). Are you unable to package Windows projects in UE5? Fear not, I have a solution for you! Reddit. Retrieved December 5, 2021, from https://www.reddit.com/r/unrealengine/comments/nm6nuz/are_you_unable_to_package_windows_projects_in_ue5/
[12] Epic Games. (n.d.-g). Environment Query System Quick Start. Unreal Engine Documentation. Retrieved December 5, 2021, from https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/EQS/EQSQuickStart/
[13] Bui, T. (n.d.). GitHub - truong-bui/AsyncLoadingScreen: Async Loading Screen. GitHub. Retrieved September 12, 2021, from https://github.com/truong-bui/AsyncLoadingScreen