[UE5] プロシージャルコンテンツ生成(PCG)最初に知っておきたいポイントと実践TIPS

新年あけましておめでとうございます!

大変遅刻しましたが、Unreal Engine (UE) Advent Calendar 2023の13日目の記事です。


UE5.2からプロシージャルコンテンツ生成フレームワーク (PCG:Procedural Content Generation Framework) が追加されました。

PCGを利用すると、大量のStaticMeshの配置などの手動では大変な作業を自動化に役立ちます。

Houdini Engine for Unreal Engineでも同じことは可能ですが、UE内で作業が完結するため、よりイテレーションを高速に回せることがメリットだと思います。

最近PCGを使う機会があったので、PCGについて最初に知りたかったポイントや、よく使うパターンの実践TIPSをまとめます。

執筆時のバージョンはUE5.3.2です。

OGP画像

UE5のサンプルプロジェクトはGitHubに公開しています。

PCGのセットアップ

以下のプラグインを有効化してください。

  • Procedural Content Generation Framework
  • Procedural Content Generation Framework Geometry Script Interop

PCGの基本的な使い方

PCGの基本的な使い方については、たくさんの入門記事があるため、今回は割愛します。

Level上にPCG Volumeを作成して、PCGのGraph InstanceにPCG Graphを設定します。

PCGの最初に知りたかったポイント

Example01: シンプルなPCGの例

Landscape上にランダムにMeshを配置し、Mesh同士がぶつからないようにするシンプルなPCGの例です。

シンプルなPCGの例 Example01 結果

シンプルなPCGの例 Example01 PCGGraph

このPCGでは、以下の4ステップの処理を行っています。

  1. ポイントの生成
    • Get Landscape Data でLandscapeを取得
    • Surface Sampler でLandscapeに対してポイントを生成
  2. ポイントの処理
    • Transform Points でランダムな移動と回転
  3. ポイントのフィルター
    • Bounds Modifier でバウンディングボックスを調整
    • Self Pruning で自己干渉しているポイントを消去
  4. StaticMeshを生成
    • Static Mesh Spawner でStaticMeshを生成

PCGではポイントを生成してから、ポイントのAttributeを何かしらの方法で加工し、最後にStatic Mesh SpawnerでStaticMeshを生成という流れになります。

そのため、ポイントにどんなAttributeが存在していて、どのように値が変化するのかを意識することがとても重要です。

この4ステップの流れは複雑なPCGでもほとんど変わらない定型パターンになります。

Inspect機能でAttributeの内容を確認する

「ポイントのAttributeの内容をInspect機能で常に確認しよう」

この記事で一番伝えたかったポイントです。Attributeの変化を意識することが、PCGマスターへの近道です。

Houdiniの経験がある方は実感できるのではないでしょうか。

参考記事: 絶対に挫折しないHoudini入門 4 - オブジェクトとジオメトリ|aoi

PCGのポイントはAttributeを持っています。これらがAttributeの具体例です。

  • Position
  • Rotation
  • Scale
  • BoundsMin / BoundsMax
  • Color
  • Density

Inspect機能は、ポイントのAttributeを内容を確認するための機能です。HoudiniのGeometry Spreadsheetに相当する機能です。

PCGの上部のタブから No Debug object selected と書かれている項目をプルダウンで変更し、現在のPCG Graph名 / PCG Compornetを選んでください。 ノードを右クリックしてInspectにチェックすると、そのノードの処理時点のPointの持つAttributeが表示されます。

ショートカットとして、ノードを選択してからAキーを押してもInspectが有効になります。

Inspect中のノードは左上に黄色い●が表示されます。

Inspect機能

Debug機能でビューポート上でポイントを確認する + Self Pruningで重なりを除去

Debug機能はViewport上でポイントを可視化する機能です。ノードを右クリックしてDebugにチェックするか、Dキーを押すことで有効になります。

Debug中のノードは左上に青い●が表示されます。

Debug機能

ビューポート上の白・黒・グレーの箱がDebugの表示です。

箱の色はDensityに対応しており、箱の大きさは ScaleBoundsMin / BoundsMax に対応します。

Self Pruning はポイントが持つバウンディングボックスのAttributeに対して判定が行われます。

そのため、ステップ3のポイントのフィルターでは、まず Bounds Modifier でバウンディングボックスを調整してから Self Pruning しています。

Inspect機能とDebug機能をつかって、ポイントのAttributeの変化を確認することが、PCGの作業効率アップやPCGへの理解度がアップにつながります。

PCGの実践TIPS

PCGでよく使いそうなパターンの実践TIPSを紹介します。

Example02: 特定のStaticMeshを避けて配置

特定のオブジェクトを避けて配置する例です。

まず手動でテーブルのStaticMeshを配置し、ActorのTagsに SM_Table を設定します。

対応前:Example01のままだと、テーブルと椅子が重なり合ってしまいます。

Example02: 対応前

対応後:重ならないようになりました。

Example02: 対応後

これがPCG Graphです。オレンジ色の枠で部分がExample01から新しく追加した処理です。

Example02: Graphの全体

Get Actor Dataの設定

Example02: GraphのGet Actor Data

Get Actor Dataはアクターを取得するノードです。

  • Actor Filter: All World Acotrs
  • Must Overlap Self: ON(Volumeの範囲内だけに限定します)
  • Actor Selection Tag: SM_Talbe(StaticMeshに設定したタグを指定)
  • Select Multiple: ON(テーブルが複数ある場合はONにします。基本的にONで良いと思います)
  • Mode: Get Single Point
  • Merge Single Point Data: ON

Differenceの設定

Example02: GraphのDifference

Differenceは差集合を計算するノードです。今回の例では、テーブルのバウンディングボックスと重なる椅子を削除します。

  • Density Function: Binary

Example02のまとめ

  • Get Actor Dataでは、Tagでフィルターすることで特定のActorやStaticMeshを取得できます。
  • Differenceを使うことで特定の範囲内のポイントを消去できます。

Example03: 特定のStaticMeshの周囲に配置

岩を手動配置して、その周りに花を自動配置する例です。

Example03: 結果

PCG Graphの全体図です。

Example03: PCG Graphの全体図

岩の周囲にポイントを生成する

まずは岩のアクターの周囲にポイントを生成します。

Example03: バウンディングボックスを指定したSurfaceSampler

Example02と同じようにTag指定で岩のActorを取得し、Bounds Modifier でバウンディングボックスを5倍に拡大します。

Surface SamplerのBounding Shapeに拡大したバウンディングボックスを指定することで、岩の周囲にポイントを生成できます。

ポイントの生成範囲を調整する場合は Bounds Modifier で5倍の数値を調整します。

Distanceノードで岩からの距離に応じたDensityを設定する

Example03: Distanceノード

DistanceノードでTargetへのPointの距離を計算できます。

SetDensityをONにして、Maximum Distanceを指定することで、距離から0-1の範囲にDensityを設定できます。

DensityをOneMinusノードで反転してから、Density Filterで中心から離れたポイントを削除します。

Densityの調整

PowやMultiplyでDensityを調整します。

Example03: でDensityを調整

定数ノードの作成

2.0や4.0の定数のノードを作成するには、Create Attributeノードを作成し、TypeをDoubeにし、Double Valueを調整します。

筆者は定数ノードの名前が分からずにしばらく悩みました😱

Create Attribute 作成

Create Attribute 設定

Static Meshの生成

最後にStatic Mesh SpawnerでStaticMeshを生成します。

Create Attribute 設定

Example04: Splineで囲んだ領域内に木を生やす

Splineで囲んだ領域内に木を生やす例です。SplineとPCGを組み合わせるためにはブループリントが必要になります。

Example04: 結果

PCG Graphの全体図です。

Example04: PCG Graphの全体図

ブループリントの作成

Actorクラスのブループリントを作成します。

Example04: ブループリント

ブループリント内にSplineを作成し、Component Tagsに ForestZone と設定します。

木を生やす目的以外のSplineを使う場合も想定して、Splineの判別用にComponent Tagsを設定しています。

たとえば、道に木を生やしたくない場合、RoadのTagを持ったSpline上にポイントをサンプリングして、 Example02で紹介したDifferenceノードで道にある木を削除するような使い方が可能になります。

次にブループリント内にPCG Componentを作成し、PCG Graphを指定します。

Spline上のポイント生成

Splineの内側にポイント生成します。

まずは Get Spline Data でブループリント内にあるSplineを取得します。

Example04: Get Spline

Actor TagsではなくComponent Tagsでフィルターするために、 Filter By Tag ノードを使いました。

Component Tagsにした方が1つのActor内に複数のSplineを生成できるので使い勝手が良くなります。

Example04: Filter By Tag

Spline Sampler でSplineの内部にポイントを生成します。

Example04: Spline Sampler

  • Dimention: On Interior(Splineの内側を指定します)
  • Unbounded: ON
  • Interior Sampling Spacingで密度を調整します

Landscape上へのプロジェクション

Transform Pointsでランダム移動とZ軸上のランダム回転してから、Spline上に生成したポイントを Projection でランドスケープ上に移動します。

Example04: Projection

木は上方向に真っ直ぐに生やしたいので、Project Rotations はOFFにしました。

重なりを除去 + StaticMesh生成

Example01でも登場した Bounds Modifier と Self Pruning のコンボ技で重なり合ったポイントを消します。

最後に Static Mesh Spawner でStaticMeshを生成して完了です。

このあたりの処理は定形パターンですね。

Example04: Projection

まとめ

PCGの基本的なデバッグ方法やよくある処理のパターンを解説しました。

PCGの基本的な処理の流れとしては、ポイントを生成して、Attributeを処理してから、最後にStaticMeshの生成になります。

InspectやDebugを使いながらAttributeの変化を確認すれば、あまり迷わずに使いこなすことができると思います。

StaticMesh上へのポイント生成だったり、複雑なPCGを作成するためにサブグラフ化する方法なども紹介しようと思いましたが、記事が長くなりすぎるので別記事にしたいと思います。

それでは良いPCGライフを!

利用させていただいたAsset

記事のサンプル作成にあたり、以下のアセットを利用させていただきました。ありがとうございます!

comments powered by Disqus

gam0022.net's Tag Cloud