【UE5】Geometry Scripting：スプラインからBlocking Volumeを作る

:::note info
対象バージョン UE5.2.1
:::

:::note info
Geometry Scriptingを使うには、Geometry Scriptプラグインを有効にする必要があります。
:::

# はじめに

進入禁止エリアなどを作るときに Blocking Volumeアクタをええ感じに並べたりする。ところが標準のBlocking Volumeアクタは箱型なので、その「ええ感じ」が意外と難しかったりする。
一方、Geometry Scriptingを使えば、任意形状の Blocking Volumeを作ることができるので、よりええ感じなボリュームが作れるかもしれない。

Geometry Scriptingで作ったDynamic MeshからBlocking Volumeを作るには「Create New Volume from Mesh」を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/d77639db-63a5-cd38-febb-0329e257b033.png)

次の動画は、
- ①スプラインで囲んだエリアからBlocking Volumeを生成する
- ②スプラインに沿わせたBlocking Volumeを生成する

…を行う自作のEditor Utilityツールの動作の様子である。こうすれば「箱型」に縛られずに、任意の滑らかな形状の進入禁止エリアを作ることができそうだ。

<iframe width="931" height="393" src="https://www.youtube.com/embed/Aqed-zWuCew" title="【UE5.2】Geometry Scripting：スプラインに沿ってBlocking Volumeを生成する" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# ①スプラインで囲んだエリアからBlocking Volumeを生成する

## Delaunay三角形分割

まずは、スプラインを囲んだエリアをポリゴン化する方法から。「Append Triangulated Polygon」を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/749620fd-a92c-ac1c-25fa-a94d58a7a0e7.png)
引数「Polygon Vertices」にポリゴン化したい頂点の座標(Vector2D)を渡すと、ええ感じにポリゴン化してくれる。特筆すべきは、凸凹した形でもええ感じにポリゴン化してくれることである。つまり、凸多角形である必要がない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/074ae406-3497-6588-40e9-4c6a8aeaf02e.png)
[ドキュメント](https://docs.unrealengine.com/5.0/ja/geometry-script-reference-in-unreal-engine/)によると、[Delaunay三角形分割](https://en.wikipedia.org/wiki/Delaunay_triangulation)を行っているとのこと。

## Extrude：ポリゴンの押し出し

スプラインで囲まれたエリアをポリゴン化したら、次はその図形をZ方向(上方向)に押し出して立体にする。ポリゴンの押し出しは「Apply Mesh Linear Extrude Faces」を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/1f7e0769-67c2-77c7-6856-23b72279bbec.png)
ポリゴンの押し出しとは、次のGIF動画のような機能である。
![20230903_ExtrudeTool.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/81831a26-d749-97ac-e9c1-a5fd66e1a6e2.gif)

後は、先に述べた「Create New Volume from Mesh」で、この押し出された形状からBlocking Volumeアクタを生成する。

## Blueprintグラフ

Editor Utility Widgetで作っている。
ユーザーインターフェース部分はこんな感じ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/ea78fb59-77fb-39c5-3d0b-c0607c2e03e0.png)
パラメータ用のDetails PanelウィジットとButtonウィジットで構成されている。

イベントグラフはこんな感じ：
![SurroundedBySpline_EventGraph.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/46201b11-8eb3-3deb-9792-b5b6f9517e10.jpeg)

この中で使われている関数 Is Mobility Staticは、選択されたアクタのRoot ComponentとSpline Componentの可動性(Mobility)が Staticかどうかを判定している。
![SurroundedBySpline_IsMobilityStatic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/ea1ebe3a-b1eb-7dc5-4a8d-447b253d853f.jpeg)

# ②スプラインに沿わせたBlocking Volumeを生成する

## ポリゴンのスイープ

ポリゴンのスイープとは、2Dの図形をパスに沿って引き延ばすような操作である。
例えば、長方形をスプラインに沿ってスイープすると、次のような形状になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/d7fc6e70-1862-99dc-db31-bd6def8e8163.png)
これをBlocking Volumeに変換してやれば、滑らかな形状の進入禁止エリアを作ることができる。

ポリゴンのスイープには「Append Sweep Polygon」を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/81fe2a84-6bd9-b484-0fd1-0ca58ad96aa3.png)

引数「Polygon Vertices」には、スイープしたい図形の頂点の座標(Vector 2D)を渡す。上の図では四角形(４頂点)を渡している。
引数「Sweep Path」には、スイープ形状、つまりスプラインの形状を点列(Transformの列)にして渡す。

後は「Create New Volume from Mesh」で、このスイープ形状からBlocking Volumeアクタを生成すればよい。

## Blueprintグラフ

こちらもEditor Utility Widgetで作っている。
ユーザーインターフェース部分はこんな感じ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/0e9d8ad6-3ffe-2a0c-0e35-85836218e678.png)
パラメータ用のDetails PanelウィジットとButtonウィジットで構成されている。

イベントグラフはこんな感じ：
![AlongSpline_EventGraph.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/54a209c8-87ac-e684-9a01-41baa2635b2a.jpeg)

この中で使われている関数Is Mobility Staticは、選択されたアクタのRoot ComponentとSpline Componentの可動性(Mobility)が Staticかどうかを判定している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/7311a4b8-4ed8-a7eb-fb5c-e221f7cb824d.png)

関数Make Base Polygonは、スイープ元の長方形の頂点配列を作成する。
![AlongSpline_MakeBasePolygon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/b659dd4c-cbc8-d9a1-c5d2-f915eb0d9469.jpeg)

関数Sample Splineは、スプライン上の点(のTransform)を一定間隔でサンプリングする。グラフ内にも書いたが、自作せずとも「Sample Spline To Transforms」という関数が標準で用意されていることに後で気づいた。
![AlongSpline_SampleSpline.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/35bf418e-ba5b-7be7-a96c-d226eb838f17.jpeg)

# 参考資料

- [UE5.0 Geometry Script - Convex Hull Blocking Volume Tool - Epic Developer Community](https://dev.epicgames.com/community/learning/tutorials/OO2/unreal-engine-ue5-0-geometry-script-convex-hull-blocking-volume-tool)
    - このツールもとても有用なので、是非。
- [Exploring Geometry Tools in UE5 | Inside Unreal - Youtube](https://youtu.be/apCSgAAkDTU)