
1. 今週の予定
1.1 映像作品としてのLevelの作成
先週、勉強した3D Gaussian Splattingを作成する上で最適と思われれる条件ので、撮影して来ました。
更に3つの条件を追加して撮影しました。
その結果を検証します。
1.2 AIの勉強
Jeremy Howard氏の Practical Deep Learning for Coders: Lesson 1 [1]の宿題の続きをやります。
先週の勉強で、教科書やYouTubeのLectureに載っていたSample Codeはそのままでは動かないでErrorになる。
Errorを防ぐにはあるWebsiteで提供されているCodeを追加する必要がある事が判明しました。
今週はそのWebsiteの勉強をします。
1.3 Materialの勉強
今週もPwnisher氏のMaterialの機能をMega ScanのDefaultのMaterialに追加する作業を行います。
1.4 Nvidia Omniverseの勉強
先週はNvidia OmniverseのLauncer、NucleusそしてDriveが一応起動するところまで出来ました。
今週はNucleusとDriveの機能について調査します。
そしてCreateを一寸だけいじってみる事にします。
後、先週まとめるのを忘れてたOmniverseの記録方法について記録します。
1.5 Gaeaの勉強
今週はGaeaの勉強は無しです。
1.6 UE5.4の新しい機能について
先週勉強したBiomeの実装をします。
Biomeの構造があんまり理解出来てないので、その辺を勉強します。
更に公式SiteのSequenceとCine Cameraの勉強も行います。
1.7 Houdiniの勉強
Houdini 19 - Wall Tool 15 [2]を勉強します。
1.8 UEFNの勉強
先週勉強した以下の公式のSiteを実装してみます。

1.9 DirectX12の勉強
Lötwig Fusel氏のD3D12 Beginners Tutorial [D3D12Ez]は SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [3]の最初の10分を勉強します。
「DirectX 12の魔導書」の勉強は、4章「Polygonの表示」の総括の続きを行います。
2. 映像作品としてのLevelの作成
2.1 撮影条件まとめ
先週、勉強した3D Gaussian Splattingを作成する上で最適と思われれる条件ので、撮影して来ました。
以下に携帯の撮影条件を記します。
<ISO>
ISOは光の感度を調整する値だそうです。
この値を上げると暗い所で撮影しても明るい画面になります。しかし同時に画像劣化が酷くなります。
高画質な画像を撮影したいならこの値は低い方が良いそうです。
一定にしました。
<WB>
White Balanceの事ですね。
Autoを外してManualに変更しました。
<EV>
「Exposure Value」の略で、露出値のことだそうです。
これがExposureの値でした。
一定にしておけば問題ないでしょう。
<彩度>
0にしました。
<コントラスト>
0にしました。
<明瞭度>
0にしました。
更に3つの条件を追加して撮影しました。
<撮影方法>
カメラを持って道を歩きます。
視線の先にカメラを構えて、あえて脇を撮影したり、下や上を撮影したりはしません。
更に一回だけ撮影します。
戻って撮影し直したりとか、逆向きに撮影したりとかもしません。
2.2 携帯を垂直に構えて撮影
開始時の画像です。

両端の画像がありません。
撮影した通りに道を進んでいきます。

両端がボケていますが、それなりに生成されています。
やっぱり一回撮影すればその方向から見る分には完璧な3Dを作成するには十分のようです。
更に進みます。

後の建物とかハリボテのようです。
更に奥に進みました。

両端がボケているとか、奥のObjectがハリボテのようになっているとか、
傾向は全部同じですね。
因みに後ろを向くとこんな感じです。

逆向きには撮影してないので撮影してない所からGaussian Splattingを作成するとこうなるという事です。
横も向いてみました。

2.3 FilmのSizeを1:1に変更
今度は撮影する動画のRatioを1:1に変更しました。

やっぱり両端はGaussian Splattingが生成されていません。
他の位置でも同じか確認してみます。


奥の建物がハリボテの様にはなって無いです。

この辺は携帯を縦にして撮影した場合より改善してるのかもしれません。
他の場所でも確認しましたが、建物がハリボテみたくなっていません。

これは偶然なのかそれともRatioを1:1にするとこうなるのか確認する必要があります。
2.4 携帯を横にして撮影
ぱっと見では、他の2つに対して両端が綺麗に生成されているような感じがしました。
以下にそれぞれの場面での画像を示します。

こうやって見ると両端はボヤケけています。
ただぼやけている範囲は他の2つと比較して少ない感じもします。
更に奥に進みました。

なるだけボケてない場所でScreenshotを取りましたが、両端にボヤっとしている箇所があります。
更に奥に移動しました。

ここは左側の木がほとんどRenderingされていません。
3つの中でもっとも質が低いです。
うーん。
確認のために見直すと、他の2つはここに木がある事すら判明してなかったです。
このSceneはほとんどぼやけてる箇所は無いですね。

後の建物にハリボテ感が出てる箇所があります。

更に奥に移動しました。

両端はやっぱりぼけていますね。
この場所から見る限りでは、奥の建物にはハリボテ感はありませんね。
2.5 3つの撮影結果を検証した感想
3つの撮影のどれも完璧な結果にはならなかったです。
正し、携帯を横にして撮影すると横のボケが少なくなるのは間違いないです。
そう言えば自転車とドラゴンの作成に使用した元のGaussian Splattingは携帯を横にして撮影していました。
携帯で撮影する場合は、携帯を横にして撮影するのは必須です。
3. AIの勉強
Jeremy Howard氏の Practical Deep Learning for Coders: Lesson 1 [1]の宿題の続きをやります。
先週の勉強で、教科書やYouTubeのLectureに載っていたSample Codeはそのままでは動かないでErrorになる。
Errorを防ぐにはあるWebsiteで提供されているCodeを追加する必要がある事が判明しました。
今週はそのWebsiteの勉強をします。
3.1 Is it a bird? Creating a model from your own data [4]を勉強します
<Step 1: Download images of birds and non-birds>
まずこれを試してみます。
以下のCodeを打ちました。

Errorになりました。
GeminiにErrorの原因を質問すると以下の回答が出て来ました。

早速試してみます。

Duckduckgo_searchがInstallされたようです。
もう一回試します。

またErrorになりました。
正し今度はddg_ImagesというFunctionがDuckduckgo_searchに無いと言っています。

との事です。
Restartの方法を聞いたら以下の方法で出来るそうです。

うーん。
2つそれっぽいのがあります。

Sessionを再起動してすべて実行するを選択します。
ぐわあ。
今までImportしたLibraryも全部Importし直してます。
これは間違えた。
なんか実行に失敗したとかの表示が写ったり消えたりしています。
終わったみたいです
あれ

今まであったErrorが消えてる?
このSessionだけもう一回実行します。

やっぱりErrorになった。
さっぱり分からん。
しかし色々検索したら以下の文章に出くわしました。

どうもddg_imagesは既にDeprecatedされてる関数のようです。
それではImport出来ないですね。
以下のようにCodeを改良しました。

これで試してみます。
以下の結果が表示されました。

Tutorialの結果も似たような感じになっていました。
これは出来たっぽいです。
はあ。
長かった。
やっとStart Lineに立つことが出来ました。
次のCodeです。

このFastdownloadというLibraryは既にImportしているのか不明です。
まあErrorが出たら判明するのでそのままやってしまいます。
Pythonは変数の型を指定しないので、どの変数がどんな型になっているのか今一理解しにくいです。
このCodeをPasteしてそのまま貼り付けました。
そして実行します。
結果です。

うおお。
出来てます。
やった。
一寸、Codeの復習をやっておきます。
Pythonは初心者ですし、Fast.aiは全く知らないですので。
しばらくは一行一行しっかり解釈してやっていきます。

Download_url()関数をFastdownload LibraryからImportしました。
![]()
変数、Destを宣言しbird.jpgをAssignします。
これが気持ち悪い、このように初期化するとDestの型は自動でStringに設定されるみたいです。
この後にDestに例えば整数をAssignしたら、その整数はStringとして保持されるんでしょうか?
それともIntに新たに変換されるんでしょうか?
![]()
Download_url()関数を早速使用しています。
これ見るとこの関数の使用方法は大体想像出来ますが、一応Documentを確認したいです。
Geminiに質問したら以下の回答が返って来ました。

試します。

これしか解説ないの?
これじゃそれぞれのParameterが何を指しているのか全く分かりません。
Copilot先生に聞いてみます。

こっちは指定されたWebsiteに行きましたが、そこにDownload_urlの説明は無かったです。
DirectにGoogleでDownload_urlを検索したら
https://fastdownload.fast.ai/core.htmlに以下の結果が表示されました。

うーん。
分からなくはないですが、あんまり親切な書き方では無いですね。
兎に角、Parameterの型に対する説明がまったくない。
Python全体がこういう説明をするんでしょうか?
urlがDownloadするFileのURL、DestがDownloadしたFileを保持するためのFolderのPath、そしてShow_progressが途中経過を報告するかどうかって感じでしょうか。
次のCodeです。
![]()
FastaiのVision.all Libraryを全部Importします。

Image型にあるOpen()関数を使用してDestにあるFileを開きます。
Image型にあるOpen()関数のReturn Valueは変数Imに保持します。
うーん。
これもDocument見せてほしいです。

最後にImageのSizeを256x256に変換しています。
うーん。
これもImの型が分からないとなんでこんな事が出来るのか不明です。
いや、もしかしてPythonだと型とか無くて全部の変数でこの関数を使用出来たりするのか。
うーん。
全然分からない。
今週はここまでにします。
4. Materialの勉強
今週もPwnisher氏のMaterialの機能をMega ScanのDefaultのMaterialに追加する作業を行います。
4.1 Pwnisher氏のMaterialの続きを勉強する
今週は先週追加したDirtのTextureにSize、Offset、そしてRotationの機能を追加します。
正し実装方法に関しては以下に示したPwnisher氏が行った実装方法をそのまま使用するのではなく、

以下に示したMega ScanのTextureの実装を参考にします。

これはこっちの方が整理されていて見やすいからです。
ただしこのMega Scanの実装はRotationの実装はTextureのUV値の後で行われているので、その部分を直す必要があります。
Material Functionを作成します。名前はTiling、Offset、そしてRotationの頭文字を取ってMF_TORとしました。

色々試したんですが、Tiling、Offsetの値をTextureを通してInputする事が出来ません。
うーん。
となるとPwnisher氏のやり方がBestになるのか。

これをそのまま使用する事にしました。
以下のようなParameterが追加されました。

テストしてみます。
Dirtが見やすいように色を黒くしました。

まずDirt Rotationです。

Dirt Rotationの値を変えると反時計回りにDirtが回転しました。
ただ全体の見た目はあまり変わって見えないです。
Dirt Tilingです。

値を2倍にしました。

Dirtの大きさが2倍になりました。
かなり印象が変わりました。
Dirt Offsetです。


Offsetの値を変更するとDirtが左右上下に移動します。
ただこのDirtに使用しているTextureの特性上、目立った変化は確認出来ないです。
これらのParameterが正常に機能しているのは確認出来ました。
これでDirtは完成です。
4.2 これからの課題
<Dirtに追加したい機能について>
今、Dirtは表面全体に均一にかかっています。
しかし実際はDirtは地面に近い部分には濃く、地面から遠い部分は薄くかかったりしています。
DirtのTextureにMaskingをかけてこのようなEffectを再現する方法を考えたいです。
<再現したい質感>
以下の質感をPhoto-realisticなMaterialで再現する必要があります。
- 金属
- プラスチック
- プラスチック(半透明)
- 布1
- 布2(レース状の隙間が空いていて奥が見えるもの)
- ガラス(透明)
- 曇りガラス
- 木材
- コンクリート
- 漆喰
- 壁に貼ってあるシールやテープ
- 紙(障子)
建物だけに限っています。
ざっと考えてこんだけありました。
この辺の調査もこれからやっていきます。
今まで10年近くUEをいじっていてこういうのが必要だったことに気が付かなかった事が驚きです。
勿論、今まではGameを作成していて今度はPhoto-realisticな映像を作成しようとしているのでその違いはありますが、それにしてももっと早く気がついても良かったと思います。
この理由ははっきり言えば、YouTubeのTutorialのせいです。
前回述べたように、YouTubeのTutorialの質は以外に高いです。
特に、
- 簡潔に難しい内容を解説する
- 最新の技術が勉強出来る
の2点においては大学の授業を超えています。
しかし欠点も同時にあり、それがこのような問題を引き起こしてしまいました。
まず、
YouTubeのTutorialはこの技術が必要だ。とかこの技術が最新だ。とか言いながら教えますが、どの技術を教えるのかを決定する要因は再生回数が稼げるかどうかだけです。
視聴者はある意味、素人ですからその技術が何故必要なのかの判断が出来ないです。
のでYouTubeのTutorialに言われるままに勉強してその技術を身に付けますが、何故その技術が必要なのかについては全く理解してないままで時間だけ経過するようになってしまいます。
次の理由は昨日気が付きました。
これは結構重要な視点なので忘れないようにここに記録しておきます。
東京都知事選が終わりましたが、石丸氏が蓮舫氏を破って二位になる大躍進を示しました。
これ、ネットの力だ。とか言われていましたが、私はそう思いません。
しかしそのネットの力と結論付けた人の中でかなり俊逸な考察をする人がいました。
その考察が何故、YouTubeのUEのTutorialは一部の例外を除いて、売れるGameを作成するために必要なものは何であるのか。という最も重要な内容を検討しないのかについての解答を示していると思われます。
その人によると石丸氏の切り抜き動画でもっとも再生されるのは相手を論破する動画だそうです。
しかし実際によく見てみると、論破するのではなく論破風の動画の方が再生回数を稼ぐ事が出来てるそうです。
内容なんかはどうでも良いそうで、論破された相手が悔しがっていたり、驚いたり、怖がったら、論破した感じになりそれで論破した事になるそうです。
私は基本的に日本語の動画は見ないのでこの話が本当かどうかは分かりません。
この後の話が非常に重要です。
実際には論破してないので彼の言っている事を真面目に聞いてもなんの益も生まない。
はい。
石丸氏の話が本当にこれに該当するかどうかは不明ですが、UEのTutorialやYouTube上に沢山あるGame批評Channelなんかはこの批評に完璧に当てはまります。
彼らの言う事を真面目に聞いてしまったから10年近く頑張ってもお金を稼ぐ事が出来るGameを作る事が出来ませんでした。
これは私が優れたGameを作成するために真剣に聞いていたGame批評Channelは論破風動画だったんです。
だからいくら真面目に聞いても何の役にも立たなかったです。
私はこの事に気が付くのに10年近くかかってしまいました。
しかし他の日本人は10年たっても気が付かないで、論破風動画を見てそれが正しいと妄信し続けるのかもしれません。
5. Nvidia Omniverseの勉強
先週はNvidia OmniverseのLauncer、NucleusそしてDriveが一応起動するところまで出来ました。
今週はNucleusとDriveの機能について調査します。
そしてCreateを一寸だけいじってみる事にします。
後、先週まとめるのを忘れてたOmniverseの記録方法について記録します。
5.1 Exploring the NVIDIA Omniverse World, Including IsaacSim [5]を勉強する
以下のChannelが偶然お勧めで表示されました。

韓国語ですが、Auto-Translationで日本語に変換したら問題なく理解出来ます。
特にこの動画です。

Omniverseの全体的な知識を得る事、そして更にIsaacSimについての概要的な知識も得る事が出来そうです。
今週は予定を変更してこの動画を見る事にします。
以下にそれぞれの章の内容をまとめます。
<00:00 Intro>
NvidiaのHomepageに行ってOmniverseがOpenUSDを使用して色々なPlatformと繋がって一種のHubとして機能するものである事を説明していました。
<01:54 Use cases (Digital Twins)>
User Casesを選択すると以下の4つが表示されます。

この4つがOmniverseが積極的に使用される分野だそうです。
この節では一つ目のDigital Twinsについて解説していました。

Digital Twinsはこの世界のReplicaを仮想空間に作成する事を指すそうです。
以下に示した様に都市を丸ごと再現して

交通やEnergy関連情報などの現実世界からのさまざまな情報を仮想空間内に再現するそうです。
生産工場を丸ごとこれで再現する事もあるそうです。
具体例として以下のPageに載っているそれぞれの例を紹介していました。

NvidiaのHomepageは今一分かりにくい構成だと思っていたんですが、こうやって説明されると何が書いてあるのかが、理解出来ます。
全体像が何となく分かりました。
Digital Twinの使用方法についても解説していました。
これは後で必要になった時に詳しく見る事にします。
<10:55 Use cases (Robotics Simulation)>
今度はRobotを使用したSimulationです。
先程のUser CassからRobotics Simulationを選択するといきなりIsaac SimのPageが現れます。

そう、こういう構成がNvidiaのHomepageを見にくくしている原因です。
트윅 tweak氏はこれはRobotic SimulationとIsaac SimがNearly Equalの関係であると解釈すべきだと述べていました。
はあ。
そうやって理解するのか。
納得。
最初の10分しか見てませんが、かなりNvidiaのHomepageの見方が分かるようになりました。
Isaac SimやLabなどの機能を説明していますが、知識が無さすぎて理解出来ません。
この辺の細かい所はもう少しIsaac Simの知識が増えてから勉強する事にします。
트윅 tweak氏の解説によると、Issac Simについては他の動画で詳しく解説しているそうです。
そっちを参考にします。
<14:27 Use cases (Synthetic Data Generation)>
Synthetic Data Generationについてです。

AIの学習にはLabelの付いたDataが必要になります。しかし実際には学習に使用出来るDataは限られており、そのDataを作成するためにお金が非常にかかるそうです。
Synthetic Data GenerationはAIの学習に必要なDataを合成して作成する事により必要なDataを少なくする事が可能だそうです。
更に人の顔のDataなどのような個人情報に関係するDataをそのまま使用すると違法行為に当たりますが、Synthetic Data Generationを使用する事で、これらの人の顔を合成する事でそのような事態を避ける事も可能になるそうです。
その他にもAccuracyやScalableと言った利点が紹介されていました。

実際の応用例として
Robotics Simulationなどが紹介されていました。

<17:50 Use cases (Virtual Factory)>
Virtual Factoryに関してです。

これは基本的にはDigital Twinsと同じだそうです。
うーん。
分かり易い解説!
<18:44 OpenUSD>
今度はOpen USDについての解説です。

Pixarによって開発された事とか、3D Graphics dataを交換するためのFrameworkとかの解説があります。
ここで3D modelと言ってない所が気になります。
単に光のDataとか背景のDataとかも含んでいるという意味でしょうか?
それとももっと深い意味があるのでしょうか?
<21:08 Omniverse Core Platforms>
Omniverseにある核となるPlatformについて解説しています。

DriveもCreateも無いです。
ConnectとかSimulationは何となく何をしているか想像出来ますが、KitとかRTX Renderは何をするためのSoftなんでしょう?
説明を聞きます。
まずこの5つのSoftはOmniverseを構成する5つの要素をそのまま表しているそうです。
この後でそれぞれのSoftの目的や機能について解説しています。
が、その部分の訳が滅茶苦茶で意味が分かりません。
唯一理解出来たのはRTX RenderがRay Tracingを使用して高解像度の3Dを作成しているという事だけでした。
<22:54 Nucleus>
Nucleusについての説明です。

私の理解はNucleusはOmniverseをServer化しているだけです。
この説明を見てもそんな感じです。
Server化する利点は、他のSoftとReal Timeで繋げられDataの更新を同時に行う事が可能な事だと思っています。
ここの説明ではあまりその点については強調されていません。
트윅 tweak氏はNucleusの機能についてGitのようなSystemを提供しているという説明をしていました。
AI-Based Deep Searchに関してですが、Nucleusには巨大なDataの中で検索する時にAIを使用する事で最速で的確なSearchが出来るようにもなってるそうです。
<24:49 Connect>
Connectについての解説です。
これは要するにUEとかBlenderとOmniverseを繋げるためのSoftでしょう。
트윅 tweak氏の説明を聞いたらよく分かりました。
例えばIsaac Simに使用する3D ModelはCreateで作成する必要があります。
しかしBlenderに慣れている人がCreateを使用すると一から勉強し直す必要が出て来ます。
これは大変非効率です。
ここでConnectを使用するとBlenderからIssac Simに直接、3D Modelを送る事が可能になります。
大変便利です。
はい。
こういう事だそうです。
これって一見便利ですけど、Nvidiaの人達が一寸勘違いしてる部分がある気がします。
BlenderでもUEでもCreateでも根本の理論は同じなので他のSoftの使い方を覚えるのはそんなに大変じゃないんですよね。
なんか新たに外国語を一個覚える必要があるとか新たに新しいProgramming言語を覚える必要があるとかいう感じにとらえていますが、方言を一個覚える位の手間なんです。Programming言語に例えるならJavaに詳しい人がC#を新たに勉強する位の感覚です。
それよりもこのConnectの使用方法を覚える方が分野が違う分、大変かもしれません。
<27:28 Kit>
Kitについての解説です。

この図を見て分かりましたが、ここで言うKitとはWindows software development kitとかで使用されているSoftwareを作るために使用出来るToolとかLibraryなどの塊と言う意味です。
これらを使用してProjectを作成する訳です。
OmniverseのProjectには以下の4つがあるそうです。

それぞれのTypeについて簡単に説明していました。
<<Extensions>>
Omniverseの最も基本的な要素だそうです。
<<Apps>>
Extensionを組み合わせて作成したものだそうです。
Isaac Simが例として挙げられていました。
<<Connections>>
Omniverseと外部のAppを繋げるためのSoftです。
<<Services>>
Nucleusなどの独立したSoftを指しているそうです。
<<>>
え、これって自分で作成するProjectの事じゃなくて既に作成されているOmniverse上のAppやServiceを指している言葉だったの。
うーん。
Kitが具体的に何を指しているのかは理解出来ましたが、その概念自体はまだよく分からないです。
例えば私がCreateを使用して作成したProjectはKitには入らないって事なんでしょうか?
この後で以下のように実際にIsaac Simを使用して説明していましたが、

これを見るとExtensionはUEにおけるPluginのようです。
分かりました。
KitはOmniverseの仕組みを別な角度から説明しているんです。
OmniverseにはIsaac SimやCreateのような独立したSoftwareがあります。
これらを総称してAppと呼びます。
このAppはExtensionというUEのPluginのような機能を何個も使用する事で作成されています。
この動画では具体的にLightingのExtensionを見せていました。
それらのAppとは別にAppと外部Softを繋げるためのSoftもあります。
Connectionsと呼ばれるものです。
先程勉強したConnectがそれに当たります。
最後に、このどれのGroupにも属さない独立したAppがあります。
これらはServiceに区分されます。
<34:30 Simulation>
ここはSimulationの内容について以下の事を説明していました。

Special EffectってVFXの事でしょう。
これもSimulationで再現するんですかね。
<35:27 RTX Renderer>
以下のPanelを使用して説明していました。

今までRenderingを私は3DのImageをPixel上で表す事と定義していました。
これは独自の定義ですがかなりあっていると自負しています。
트윅 tweak氏はここでRenderingの定義を3DのModelを平らなImageとして表す事だと言っていました。
これは私の言っている定義とほぼ同じです。
一番興味のある複数のVideo Cardを使ったRenderingについては何の解説も無かったです。
どうやって3Dを作成するのかについての簡単な解説もしていましたが、ここは私の得意分野であるのでここにまとめるのはSkipします。
<42:20 Omniverse Summary>
今までの解説を簡単にまとめていました。
ここの部分の日本語訳はそのほとんどが滅茶苦茶で何を言っているのか全然分かりません。
<43:36 Omniverse Conclusion>
Omniverseの評価をするそうです。
これも日本語訳が滅茶苦茶で何を言っているのか不明です。
分かったことだけ以下にまとめます。
- システムが巨大で、複雑。更に必要とするHardwareも高額なので使用するための敷居が高い。
- でも得られる対価も凄いのでやる価値あり
- 将来性は非常にある。(特にロボット市場)
<45:26 Job Openings Related to IsaacSim(South Korea)>
関係ないのでSkipします。
<47:25 Omniverse Launcher Install>
この辺は先週勉強した内容です。
これ見ると最初に言ったSDKのDownloadをすると

Omniverse LauncherがInstallされるみたいです。
なんだ。
そうだったのか。
<49:00 Running Omniverse Launcher>
Launcherの説明をしています。
この辺は変な日本語訳で勉強するより英語の動画を見ます。
変な日本語訳をずっと読んでいたのでなんか頭が痛いです。
<54:52 Outro>
特になし
5.2 Exploring the NVIDIA Omniverse World, Including IsaacSim [5]を勉強した感想
大体Omniverseがどんな仕組みなのか理解出来ました。
こんなに良いSoftwareなのにYouTubeにはこれ関連のTutorialが少なすぎます。
やっとOmniverseの概要が理解出来ました。
今週はもう時間がないので、Driverの機能とかCreateを試しに使ってみるとかは来週以降やる事にします。
今週はここまです。
6. Gaeaの勉強
今週はGaeaの勉強は無しです。
7. UE5.4の新しい機能について
先週勉強したBiomeの実装をします。
Biomeの構造があんまり理解出来てないので、その辺を勉強します。
更に公式SiteのSequenceとCine Cameraの勉強も行います。
7.1 Create Biome with PCG with this New Biome Plugin in Unreal Engine 5.4 ! [6]を実装する
<Intro>
特になしです。
<Enable all the PCG Plugin>
PCG Biome Sample以外のPluginをEnableしました。

UE5を再起動します。
<Creation of the Forest Biome>
PCGのFolderを作成して、その中にBiomeのFolderを作成して、その中にForestのFolderを作成します。

しました。
Biome Asset Templateを追加します。

BT_Forestと名付けました。
開くと以下のようになっていました。

+を押すと以下のようになりました。

Tutorialと同じ結果になっていますね。
GeneratorにDefault Generatorをセットしました。

次にMeshに以下のTreeをセットしました。

ForestのFolderに戻ってまたData Assetを選択します。
今度はBiome Definition Templateを選択します。

BD_Forest_Definitionと名付けました。

開くと以下のようになっていました。

Biome NameにForestBiomeと入力します。

BiomeColorの色をGreenに設定しました。

Tutorialの説明によるとTexture上でこのGreenの色を持つところは全部、ForestBiomeと認識されるそうです。
今度はBPを作成します。
BP_PCGBiomeSetupを親Classとして選択しました。

生成したBPにBP_ForestBiomeSetupと名付けました。

このBPをLevel上に配置するんですが、このTutorial用のLevelをまだ作成していません。
今ここで作成します。

出来ました。
BP_ForestBiomeSetupをLevel上に配置しました。

BP_ForestBiomeSetupを開き、DefinitionにBD_Forest_Definitionをセットします。

更にAssetsのIndex[0]にBT_Forestをセットします。

<Setup of the PCG Biome Core and PCG Biome Spline>
今度はBiomes Folderまで戻ってBPを作成します。

BP_PCGBiomeCoreを親Classとして選択します。
名前はBP_BiomeCoreとしています。

Biome CoreをLevel上に追加します。

Landscape全体がCoreで覆えるようにSizeを調整しています。
Scaleの値を以下のように変更しました。

結果です。


また先週のBlogでは以下のように書かれていますが

調べた限りでは無かったです。
またBPを作成します。

BP_PCGBiomeSplineを親Classに選択します。
BP_BiomeSplineForestと名付けました。

以下のように配置しました。

DefinitionとAssetsに以下のAssetをセットします。

BP_BiomeCoreを選択して

BiomeCoreを選択します。

更にPCGのGenerateを押します。

結果です。

何の変化もありません。
先週のBlogでは以下のように書いてありますが

BP_BiomeCoreにはこんな項目はありません。
Tutorialを見直します。
BiomeCoreでこのParameterを使用しています。
もう一回確認します。

ありました。
結果です。

これでTreeが形成されるような設定にはなっている事が確認出来ました。
今度はBT_Forestを開きます。
Asset OptionにあるSelfPruneをOnにします。

先週のBlogにはこれをOnにするのかOffにするか不明だ。と書いていました。

DefaultではOffになっていたのでOnにします。
次は以下の部分をやります。

ここです。

Zminの値を-500にしました。
これでTreeが生成されるはずです。

あれ?
生成されません。
何で?
Biomeの勉強する時間はもう無いです。
今週はここまでにしてTreeが生成されない問題は来週検討する事にします。
7.2 Sequencer Editor [7]を勉強する
先週は以下の場所で終わっていました。

Playheadを右ClickするとこのBoxが表示されます。

今週はこれらのそれぞれの機能について調べます。
<Set Start Time>

これがStart Timeを指定する機能という事は分かりますが、Hotkeyは何なんでしょう?
これ押すとSet Start Timeと同じ効果があるんでしょうか?
Testします。
以下の条件でTestします。
Playheadが2.10秒の位置にあります。

[を押しました。

Start Timeの位置が変わりました。
うーん。
Shortcut Keyと呼んで欲しかった。
<Selection Range>
以下の2つがまったく意味の分からない機能です。

Sequencer Editor [7]を読むとSelection Rangeと言うのがあって

それをこのSet Selection StartとSet Selection Endで指定出来るそうです。
やってみます。
以下のように指定出来ました。

でもこれが指定出来るとどうなるんでしょうか?
この後、Sequencer Editor [7]ではこのSelection Keyの操作方法がずらっと説明されていますが、これを使用出来ると何が出来るのかの説明はありません。
消します。
消し方はPlayheadを右Clickして以下のBoxを表示させ、

Clear Selection Rangeを選択するだけです。
<Custom Frame Marks>
今度はAdd Markです。

これも何に使用するのか不明です。
とりあえず使い方だけ覚えておきます。
まず試しに追加してみました。

Playheadがあった場所にAと名前の付いたBarが追加されました。
Aを右Clickすると以下のBoxが表示されます。

Labelの値をSidewayに変更してみました。

Markの名前がSidewayに変りました。
Sequencer Editor [7]では、Markの操作方法について詳しく解説していますが、このMarkが何に使用出来るのかは説明されていません。
まあ当分は使用しないでしょう。
消します。
消し方はPlayheadを右ClickしてBoxを表示させ、Delete MarkかDelete All Marksを選択するだけです。

<Locked>
これは2つあります。
Start TimeとEnd Timeの下にあるLockedは、Start TimeとEnd Timeが動かないように固定します。
MarkにあるLockはMarkを固定したりMarkの追加や削除を禁止したりします。
7.3 Sequencer EditorCine Camera Actor [8]を勉強する
先週はLook at Trackingを勉強しました。
そして最後に以下のように書き残していました。

今週はこれをTestします。
以下のようにCameraの前に白い球を配置して

CameraのTrackingにこのSphereをセットします。

この状態でPlayを押します。
結果です。
これで先程の質問の答えは明白です。
CameraはTrackingで指定されたMeshを追い続けますが、Cameraの位置は変化しません。
8. Houdiniの勉強
Houdini 19 - Wall Tool 15 [2]を勉強します。
8.1 Houdini 19 - Wall Tool 15 [2]を勉強する
このTutorialでは偽のDestruction Effectを追加するそうです。
まず以下に示した様に先週繋げたInputを外します。

以下のようなVolumeを追加して

その部分にはBrickが生成されないようにするそうです。
Sphereを以下の位置に移動しました。

もしSphereのGizmoが表示されてない場合は、KeyboardのEnterを押せば表示されるそうです。
Brick Wall Tool_Buildを開き、Attribwrangle_ShuffleBricksノードを選択します。

と思ったらその下のConvert Line1ノードを選択しました。

この辺のNodeの実装を変えていくみたいです。
実装を追加するSpaceを確保するために以下の部分を左に移動させます。

更にConvert Line1ノードより下の部分は更に下に移動させて上下のSpaceも作成しました。

以下のIconをOnにして

以下のような表示にします。

ここでは数字の表示が追加されています。
Groupノードを追加します。

Group5を可視化すると

以下のようになります。

Group Nameの値をBlastBrickに変更します。

Group Typeの値はPointsに変更します。

Base GroupのEnableをOffにします。

そしてKeep in Bounding RegionsをEnableします。

すると以下のようなBoxが表示されます。

そしてBounding Typeの値をBounding Object{Point or Vertices Only}に変更します。

<Bounding Regions>3:11
この状態でGroup 5ノードの右端のInputにSub-Network Input #2を繋げます。

Group5ノードはErrorを表示していますが、
一個上の階層に戻って

Sphere1をBrick Wall Tool_Buildノードに繋げます。
するとGroup5ノードのErrorが消えます。

今度はBlastノードを追加します。

BlastノードのGroupの値をBlastBrickに変更します。

以下のようになりました。

あれ。
これが出来たらもうほぼ完成じゃね。
何で後10分もTutorialあるんでしょう。
Tutorialで以下のPointが問題だって言っていました。

このPointはPolygonを形成しないので消す必要があるそうです。
Facetノードを追加します。

Remove DegenerateをEnableします。

Facet1ノードを可視化します。

先程のPointが消えています。
もしくはAttribwrangleノードを追加して

以下の実装を追加します。

これらの2つのNodeの結果はまったく同じです。
以下のBoxを表示させLast Cookを見ると

Attribwrangleノードでは計算するのに0.02 msかかっています。
それに対してFacet1ノードでは0.06 msもかかっています。

のでこのTutorialではAttribwrangleノードを使用するそうです。
Switchノードを追加します。

ConvertLine1ノードの結果をSwitch3ノードに繋げます。

そしてAttribwrangle2ノードの結果をSwitch3ノードに繋げます。

うーん。
この辺は何をやっているんでしょう。
InputしたVolumeでBrickを消すか消さないかの選択でも出来るようにするんでしょうか?
SwitchノードのParameter Paneは以下のようになっています。

Convert Line1ノードが0、Attribwrangle2ノードが1に繋がっています。
ここにInputがある場合は1を選択するCodeを追加するのか。
成程。
やっている事分かりました。
<Expression Editor>8:17
Select Inputを選択した状態で

Alt Eを押します。
Tutorialではこのように述べていますが、
動画を見てるとSelect Inputそのものではなくその値を選択しているように見えます。
どっちが正解なんでしょうか。
これは実装する時に確認します。
すると以下に示したEdit Expressionが表示されます。

以下の実装を追加しました。

前回とはInputの順番が違うから==0になっているのでしょうか。
この実装の詳細は後で検証します。
今度は別なErrorを直します。
それは以下のようにBrick Wall Tool_BuildノードのInputに何も繋がってない状態にすると

Errorになる事です。

<Add an Expression>10:18
このErrorを直すにはExpressionを追加する必要があります。
Group5ノードを選択して
Keep in Bounding RegionsのEnableを右Clickして以下のBoxを表示します。
そしてEdit Expressionを選択します。

Edit Expressionが開きました。

以下の実装を追加しました。

この実装の内容も後で検証します。
以下に示した様にKeep in Bounding RegionsのEnableの表記が変化しました。

更に以下のNodeのErrorが消えました。

Switchノードの結果を
以下に示したForeach_Begin1ノードに繋げます。

Output_Brick Wall Outputノードを可視化します。

結果です。

上の階層に移動します。
Sphere1ノードを繋ぎます。

結果です。

うん。
これで完成なのか。
なんか出来てそうです。
それぞれのPointのNumberを表示させている意味が無かった気がしますね。
もしこれで完成ならば。
Sphereの位置を移動させています。

これも問題なさそうです。
以下のような2つのSphereをMergeさせた形状を使用する事も当然出来ます。

結果です。

2つのSphereに削られた形状のWallが生成されました。
今度はCurve1ノードを追加しました。

結果です。

破壊された城壁って感じがしますね。
あれ、この後、Tutorialの総括とか始めています。
これが最後のTutorialでしたっけ。
Playlistを確認すると以下のようになっていました。

Unreal Engine Tipsがありますが、HoudiniのTutorialとしては、最後のTutorialになるのか。
うーん。
なんか感無量です。
9. UEFNの勉強
先週勉強した以下の公式のSiteを実装してみます。

9.1 Create Custom NPC Behavior [9]を実装する
これは公式のSiteのTutorialになるので新しいProjectを作成します。
名前はOfficial Tutorialとします。
<Creating a New NPC Behavior Script>
以下のWindowからNPC Behaviorを作成します。

NPC Behavior Nameの値をmy_first_npc_behaviorに変更します。

Createを押します。
以下に示したようにmy_first_npc_behavior.verseが作成されました。

VS Codeが開きました。

Saveします。
UEFNに戻ってBuildします。

NPC Character Definitionsを作成します。

名前はどうしましょう。

Class名がNPC_Character_DefinitionなのでCD_MyFirstNPCとしました。
CD_MyFirstNPCを開き以下のようにmy_first_npc_behaviorをセットしました。

CD_MyFirstNPCをLevel上に配置します。

おお、勝手にNPCが選択されています。
しかもNPC Spawnerが配置されています。

先週のBlogやCreate Custom NPC Behavior [9]を読むとここで一回Game PlayをしてNPCが動いている事を確認しています。
やってみます。

NPCが生成されました。
生成されたNPCはある場所まで歩いて移動します。その場所に一定時間留まると、今度は元の場所に戻って来ます。
うん。
以下に書かれてた内容通りの行動をしてます。

<Navigatable>
Navigatableを実装します。
と思ったらDefaultで実装されていました。

実装の仕方も先週のBlogで予測した通りでした。
先週のBlogでは次に以下のように書いていました。

DefaultのCode内からNPCSpawnPointの初期化の実装を探してみます。

ありました。
要は先週勉強した実装は、自分で書くのではなくDefaultで用意されているものだったんです。
これなら簡単です。
ではDefaultのCodeに沿って先週勉強した内容を確認していきます。
次の内容です。

これもDefaultのCodeを見たら書かれていました。
まずNavResultGotoの実装方法が少しだけ違っていました。

この後に
移動が終わったらその場所に待機するためのCodeがありました。

そして以下の実装で元の場所に戻る様になっています。

ただしこのCodeは以下に示した様に
Race内で使用されています。

このRaceの使用方法はまだ分かりません。
というか実際に使用しているのを見たのは初めてです。
<Focus>
今度はFocusについてです。
以下の方法で初期化していました。

MaintainFocus()関数でFocusするPointを指定していました。

<Leashable>
これもDefaultのCodeにあるかと思ったらありません。
うーん。
今週はこれだけ出来たら十分です。
これ以降は来週勉強する事にします。
10. DirectX12の勉強
Lötwig Fusel氏のD3D12 Beginners Tutorial [D3D12Ez]は SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [3]の最初の10分を勉強します。
「DirectX 12の魔導書」の勉強は、4章「Polygonの表示」の総括の続きを行います。
10.1 Lötwig Fusel氏のD3D12 Beginners Tutorial [D3D12Ez]を勉強する
10.1.1 SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [3]の最初の10分を勉強する
このTutorialではSwapChainについて勉強します。
最初の2分位でこのSwapChainの機能について解説しているんですが、何言っているのか聞き取れません。
で、BlogでSwapChainの機能について検索したんですが、出て来ません。
「DirectX 12の魔導書」を読み直したら、SwapChainの機能は画面の切り替えだと書かれていました。
思い出しました。
DirectX12では画面のチラつきを無くすために、裏の画面でPixelのDataを貯蓄しておいてそのImageが完成したら、表に表示されているImageと交換するんでした。
それを担当するのがSwapChainでした。
ここまで思い出したら、Blogにまとめた箇所も見つかるでしょう。
もう一回探します。
ありました。
2023-03-13のBlogでは以下のようにまとめられていました。

更にその次の週の2023-03-20のBlogでは
SwapChainの生成方法についてまとめてありました。

これを理解した上でもう一回、 SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [3]の最初の2分を見直します。
今度は何が言いたいのかは何となく理解しました。
簡単にまとめるとSwapChainは、前回のTutorialで作成したWindowのSizeぴったしのImageを作成する。と言っています。
Double Bufferについては何の解説もしていませんでした。
それではSwapChainを作成していきます。
Window.h Fileを開き、以下の場所にComPointerを使用してSpawnChainのObjectを宣言します。

今度はWindow.cppに移動してCreateWindowExW()関数の後に以下の実装を追加し、

その後にSwapChainを初期化するための実装を追加していきます。
SwapChainを初期化するためにはFactoryが必要だそうです。
先程Blogを検索してた時にこのFactoryの話がちらっと出て来たんですが、どんな機能なのかおぼえていません。
DirectX12に必要なそれぞれの機能は全部Deviceから生成するじゃなかったんでしょうか?
何でSwapChainはFactoryから生成するようになってるんでしょう?
これについては後で調べる事にします。
まずFactoryを作成します。
DXContext.h Fileに移動して

以下の実装を追加します。

ComPointerを使用してFactory型の変数を宣言しています。
DXContext.cpp Fileに移動して以下の実装を追加します。

なんとDeviceを作成するよりも先にFactoryを作成しました。
うーん。
FactoryとDeviceの関係が知りたいです。
更に生成したObjectをReleaseするための実装も追加します。

Deviceより先に生成したんですから、Shutdown()関数の最後に追加します。
またDXContext.h Fileに戻って来て、今度はFactoryのGetterを作成します。
以下の場所に作成しました。

Window.hに移動します。
Window.hからDXContent.hが使用できるようにIncludeします。

そして最初のWindow.cppに戻って来ます。
そして以下の実装を追加します。

CreateSwapChainForHwnd()関数を追加します。

このCreateSwapChainForHwnd()関数のParameterの説明が結構重要です。
まず最初のParameterですが、関数の説明のところではDeviceとなっていますが、

実際にはCommand Queueを追加します。
この間違いは関数の説明に使用されているDocumentがDirectX11とDirectX12で同じものが使用されているから起きているそうです。
ふーん。
今は直っているんでしょうか?
更にParameterに使用するためのArgumentを作成します。

生成したArgumentを追加します。
![]()
その後に更にnullptrを追加します。
今度はComPointerを使用してSpwapChain1を作成します。

あれ?
最初に以下に示したSwapChain3を宣言していたじゃないですか?
何でこれ使用しないんでしょう?

分からん。
ここで作成したsc1を追加しました。

何と、この後で、QueryInterface()関数を使用してSwapChain3であるm_swapChainに値をPassしていました。

うーん。
SwapChainの作成ってこんなに複雑だったのか。
丁度ここで10分30秒経ちました。
今週の SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [3]の勉強はここまでとしておきます。
10.1.2 SwapChain | D3D12 Beginners Tutorial [D3D12Ez] [3]の最初の10分を勉強した感想
2つ分からない所があります。
まずFactoryという概念です。Deviceと分けて存在しているがDeviceとはどう違うんでしょうか?
次にSwapChainの生成においてCreateSwapChainForHwnd()関数を使用していますが、こんなに複雑な使用方法だったのか覚えていません。
この2つの分からない所を調査する事にします。
<Factoryという概念について>
DirectX12はDeviceに全体を監視させ、それぞれの機能は分割してDeviceから生成されるClassに担当させています。
つまりDeviceが全部管理しています。
にもかかわらず何でSwapChainはFactoryと言う別な存在から作成する必要があるんでしょうか?
謎です。
答えが見つかるか分かりませんが調査します。
まずは「DirectX 12の魔導書」でその辺に関係した記述がないか調べます。
ありました。
「3.2.2 DirectX12の初期化」に以下の記述がありました。

DeviceはID3D12から作成していますが、SwapChainとFactoryはIDXGIから作成しています。
DXGIはDirectX Graphics Infrastructureの略だそうです。
そしてDirectX Graphics Infrastructureは以下に示したように、

https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/d3d10-graphics-programming-guide-dxgi
DirectX12よりも低層のAPIで、
Displayの出力に直接関係する機能を制御しているそうです。
成程ね。
Displayへの表示はDirectXの範囲外だから、Deviceでは担当する事が出来ないのか。
それでFactoryをDirectX Graphics Infrastructureから生成してそのFactoryにSwapChainを作成させているのか。
納得。
Deviceを親会社に例えて、Deviceから生成されるそれぞれのObjectを子会社に例えましたが、それに沿った例えをするとFactoryは大学ですね。会社では直接出来ない専門的な研究をするために大学と共同で作業するって感じです。
この場合Factoryが学会そのものでSwapChainがその研究を担当する教授って感じでしょうね。
完全に謎が解けました。
次に行きます。
<CreateSwapChainForHwnd()関数のParameterについて>
CreateSwapChainForHwnd()関数のParameterがこんなに複雑だったかどうか全く覚えていません。
これも確認します。
やっと見つけました。
「DirectX 12の魔導書」の勉強では「3.3.4 Swap Chain」の「Swap Chainの生成」で実装していました。
2023-04-17のBlogで勉強しています。
以下のように書いてありました。

はい。
CreateSwapChainForHwnd()関数のParameterに関してはSample Codeからの丸写しで、全く検証していませんでした。
うーん。
これ教科書でも何も書かれていなかったんでしょうか。
それも確認します。
P78に「DeviceなのになんでCommand Queue」という題でしっかり説明されていました。
これで一見落着と思ったら、SwapChain()関数のParameterの謎はもう一個ありました。
最後のParameterに使用するSwapChainのObjectです。
これが敢えてIDXGISwapChain1を使用している点です。

最初にIDXGISwapChain3でSwapChainを宣言しているにも関わらず、ここでは敢えて別のSwapChainのObjectを作成して、そのObjectに値を受け取らせて、
最後に以下の実装を用いて
![]()
値をPassしています。
こんな面倒な事を「DirectX 12の魔導書」のSwapChainの実装でもやっていたのか確認します。
最初のSwapChainの宣言ですが、IDXGISwapChain4で宣言しています。

CreateSwapChain()関数内のParameterでは

IDXGISwapChain1に型を変換して使用していました。
うーん。
これだったら最初からIDXGISwapChain1を使用した方がいいんじゃないの?
ここに関しては特に説明はしてないです。
以上でした。
10.2 「DirectX 12の魔導書」を勉強する
10.2.1 「4章Polygonの表示」の総括の続き
前回勉強した「4.9 Root Signature」を実装しています。
「4.10 ViewportとScissor Rectangle」を勉強しています。
ViewportはPCの画面に対してどのようにRenderingした画像を表示するのかを指定する箇所だそうです。
ただしViewportはそれだけではそのまま画面として表示されないそうです。
Viewportのどの部分を画面に表示するのかを決定するのがScissor Rectangleだそうです。
「4.10.3 描画命令」も勉強していました。
以下の手順で描画するそうです。

「4.10.1 Viewportとは」と「4.10.2 Scissor Rectangleとは」を実装しています。
なし
「4.10.3 描画命令」を勉強しています。
「4.10.3 描画命令」を実装しています。
「4.11 三角形ポリゴンを四角形にしてみる」を勉強しています。
「4.11 三角形ポリゴンを四角形にしてみる」の「4.11.1 Primitive Topologyを変更する」を勉強しています。
「4.11 三角形ポリゴンを四角形にしてみる」の「4.11.1 Primitive Topologyを変更する」を実装しています。
「4.11 三角形ポリゴンを四角形にしてみる」の「4.11.2 Indexを利用する」を実装しています。
ここで「4章Polygonの表示」が終わりになっています。
10.2.2 「4章Polygonの表示」の総括した感想
うーん。
まだ「4章Polygonの表示」が何をやったのか把握出来ないですね。
というかこれを何度繰り返しても、理解出来なそうな気もしています。
こういうのは全体の知識が増えて、自分のDirectX12のLevelが上がったら、自然に理解出来るはずです。
「4章Polygonの表示」の総括はここまでにして来週から「5章 PolygonにTextureを貼り付ける」を勉強します。
11. まとめと感想
なし
12. 参照文献(Reference)
[1] Jeremy Howard. (2022, July 21). Practical Deep Learning for Coders: Lesson 1 [Video]. YouTube. https://www.youtube.com/watch?v=8SF_h3xF3cE
[2] Rick Banks. (2022, June 28). Houdini 19 - Wall Tool 15 [Video]. YouTube. https://www.youtube.com/watch?v=VVuTImH7V5g
[3] Lötwig Fusel. (2023, June 14). SwapChain | D3D12 Beginners Tutorial [D3D12EZ] [Video]. YouTube. https://www.youtube.com/watch?v=IE1wTLVpVRg
[4] Jhoward. (2022, August 15). Is it a bird? Creating a model from your own data. Kaggle. https://www.kaggle.com/code/jhoward/is-it-a-bird-creating-a-model-from-your-own-data
[5] 트윅 tweak. (2024, June 30). IsaacSim을 포함하는 NVIDIA Omniverse 세계관 알아보기 [Video]. YouTube. https://www.youtube.com/watch?v=5tNA2lgtqZE
[6] Nicolas Noseda. (2024, April 14). Create Biome with PCG with this New Biome Plugin in Unreal Engine 5.4 ! [Video]. YouTube. https://www.youtube.com/watch?v=GpvnXhpuvy4
[7] Sequencer Cinematic Editor Unreal Engine | Unreal Engine 5.4 Documentation | Epic Developer Community. (n.d.). Epic Developer Community. https://dev.epicgames.com/documentation/en-us/unreal-engine/sequencer-cinematic-editor-unreal-engine
[8] Cinematic Cameras in Unreal Engine | Unreal Engine 5.4 Documentation | Epic Developer Community. (n.d.). Epic Developer Community. https://dev.epicgames.com/documentation/en-us/unreal-engine/cinematic-cameras-in-unreal-engine?application_version=5.4
[9] NPC Character Definitions. (n.d.). Epic Dev. https://dev.epicgames.com/documentation/en-us/uefn/npc-character-definitions-in-unreal-editor-for-fortnite