「Building Generator」
【 開発環境 】
Blender Python API / Unreal Engine C++
【 システム概要 】
キューブで概形を設定、それに沿って壁や床などのパーツを配置し、建物を生成するシステムです。このキューブの概形もある程度自動で生成できるようになっており、それを微調整して、最後にパーツを生成する、というワークフローを想定しています。

パーツモデル

【 目的 】
本作は以下の2点を主目的として制作しました。
・UE上で、大量のオブジェクトを用いて、巨大な建築物が生成できるかを検証する。
・BlenderとUEの連携方法を勉強する。
【 ワークフロー 】
このセクションではパーツ登録から建物生成までのワークフローをご紹介します。
Blenderでパーツをモデリングし、エクスポートします。モデルと併せて当たり判定のデータもBlenderからエクスポートします。本システムはパーツを敷き詰める際に、ボクセルベースで当たり判定を行っています。Blender上でEmptyを配置する事で、ボクセルの有無を設定します。

左: パーツモデル
右: モデルの当たり判定

UEのデータアセットにモデルと当たり判定のデータをインポートします。

パーツのデータアセット

詳細は省略しますが、各データアセットは以下の様な階層構造になっており、パーツの出現頻度などを細かく設定できるようになっています。

データアセットの階層構造

最後にシード値を設定し、実行ボタンを押すと、レベルのキューブが走査され、その形状に沿ってパーツが生成されます。

シード値のデータアセット

左: キューブの概形
右: 概形から生成された建物

【 プログラムの方針 】
本システムは全てC++で記述しています。理由は以下になります。
(1) 規模が大きくなり、複雑性が増すと、C++の方がリファクタリングしやすいと感じるため。
(2) 探索など計算量が多い処理も、C++であればある程度高速に処理できるため。
(2)の恩恵が非常に大きいです。本システムはもともとBlender Python APIやUnityで構築していたのですが、それらと比較して非常に処理時間が短く、調整作業のイテレーションが回しやすいです。

ソースコード

【 技術的な試み 】
●Hierarchical Instanced Static Mesh(以下HISM)の使用
描画負荷を軽減するために、パーツ1つ1つをスタティックメッシュとして表示するのではなく、HISMのインスタンスとして表示しています。具体的には、建物自体は1つのアクターとなっており、そこに複数のHISMコンポーネントがアタッチされている、という作りになっています。

HISMの使用例

●内容がランダムに切り替わる看板の作成
看板の内容の数だけマテリアルを用意する事は、あまり効率的ではないと考えたため、インスタンスIDに応じて内容がランダムに切り替わるマテリアルを作成しました。

インスタンスIDに応じて内容がランダムに切り替わる看板

具体的には、AEで、テキストから以下のようなテクスチャを生成するスクリプトを作成し、マテリアル内でインスタンスIDに応じてクリッピングを行っています。

左: テキストレイヤーを自動整列するスクリプト
右: スクリプトを用いて作成したテクスチャ

インスタンスIDに応じてランダムにクリッピングを行うマテリアル