UE4で、3Dモデルの断面を表示させるために、UE4マテリアルのBoxMask-3Dを利用しました。
他にももっと良い方法がありましたら、ぜひコメントにお願いします!
動作環境
- UE4.24.3
- Windows 10
- GeForce RTX2070
参考サイト
- SphereMaskですが、とても参考になりました。
- Create dynamic mask within overlapping volume - Unreal Engine Forums
- Location Based Opacity in UE4 - Part1 - YouTube
- Location Based Opacity in UE4 - Part2 - YouTube
- UE4 Object Mask l Unreal Engine 4.26 (Tutorial)
- BoxMaskの回転追従
- https://forums.unrealengine.com/development-discussion/rendering/97595-boxmask-3d-rotation-question#post1640080
断面表示させたい3Dモデルを用意
- UE4でアクタマージしたメッシュ(1メッシュ、1マテリアル)を使うことを前提 に書いています。
- 使用する3Dモデルを任意のマップに配置し、アクタマージ、マテリアルマージをしておきましょう。
断面表示するオブジェクト
マテリアルパラメータを作成
先に、マテリアルのBoxMaskで使用するマテリアルパラメータを作成しておきます。
マテリアルを作成
- コンテンツブラウザ上で右クリック > マテリアル を選択し、M_CrossSectionを作成します。
- 詳細タブで、MaterialのBlendModeをMaskedに変更します。
- マテリアルノードは下図の通りです。
BoxMask-3Dの引数の内訳は以下の通り。
- A : World Position Offset(板に追従しているBoxの回転値を渡しています)
- B : マスクの中心点
- Bounds : BoxのサイズをVectorで指定
- Edge Falloff : エッジを柔らかく(Boxの角に丸みを持たせる)
引数Aで、Boxの回転値をVectorで直接渡そうとしたら上手くいかず、回転軸の計算の順番が関係していて、こちらの フォーラム を参考にノードを組みました。
BaseTextureでは、デフォルトのテクスチャ(今回は、/Engine/EngineMaterials/Grid)を設定しています。
断面表示するオブジェクトのブループリントクラス
-
コンテンツブラウザ上で右クリック > ブループリントクラス > すべてのクラス > StaticMeshActorを選択し、BP_CrossSectionを作成します。
-
コンポーネントタブで、コンポーネントを追加 をクリックし、StaticMeshを追加します。
- 詳細タブ > コリジョン で、
- コリジョンプリセット : Custom
- ObjectType : WorldDynamic
- 詳細タブ > コリジョン で、
-
変数を追加します。
- MaskedMesh (Static Mesh型、 インスタンス編集可能にチェックを入れる )
- Material (Material Instance Dynamic型)
- DiffuseTexture (Texture型)
-
Construction Scriptで、下記の通りにノードを組みます。
断面表示させるための板
透明マテリアルを作成
- コンテンツブラウザ上で右クリック > マテリアル を選択し、M_PlaneTranslucentを作成します。
- 詳細タブで、BlendModeをTranslucentに変更します。
- オパシティに定数0.2を渡してあげます。(ガラスっぽいマテリアルとか凝りたい方はご自由にどうぞ)
板の枠線をUMGで作成
透明な板だと、板を見つけられないので、枠線を表示させるためのUMGを作成します。UMGでなくても他の方法でも良いですが、今回はこれで。
- コンテンツブラウザ上で右クリック > ユーザーインターフェース > ウィジェットブループリント を選択し、CrossSectionPlaneUMGを作成します。
- パレットタブで Border を検索し、階層タブの CanvasPanelの下にドラドラで追加します。
- 階層タブのBorderをクリックし、詳細タブで値を変更します。
- スロット
- サイズX : 1250
- サイズY : 850
- コンテンツ
- Content Color and OpacityのRGBA: 1.0, 1.0, 1.0, 0.0
- アピアランス
- Brush : 枠線以外を透過した画像(↓こういうの)を用意して、UE4にインポートし、その画像を設定してください。
- スロット
板のブループリントクラス
- コンテンツブラウザ上で右クリック > ブループリントクラス > よく使うクラス > Actor を選択し、BP_CrossSectionPlaneを作成します。
- コンポーネントタブで、コンポーネントを追加 をクリックし、下記の3つのコンポーネントを追加します。
-
Plane (Static Mesh)
- トランスフォーム
- 位置 : 0.0, 0.0, -250.0
- 拡大・縮小 : 0.34, 0.5, 0.001
- 可動性 : ムーバブル
- Static Mesh: Cube(/Engine/EnngineMeshs/Cube)
- Materials: M_PlaneTranslucent(先ほど作成したもの)
- Collision
- コリジョンプリセットをCustom
- ObjectTypeをPhysicsBody に変更
- トランスフォーム
-
Frame (Widget Component)→Planeの子に配置
- トランスフォーム
- 回転 : 0.0, 90.0, 0.0
- 拡大・縮小 : 1.0, 0.215, 109.0
- 可動性 : ムーバブル
- ユーザーインターフェース
- Widget Class : CrossSectionPlaneUMG(先ほど作成したもの)
- Draw Size : X 1250, Y850
- トランスフォーム
-
Box (Static Mesh)
- トランスフォーム
- 拡大・縮小 : 1000.0, 1000.0, 500.0
- 可動性 : ムーバブル
- Static Mesh: Cube(/Engine/EnngineMeshs/Cube)
- Materials: M_PlaneTranslucent(先ほど作成したもの)
- Collision
- Generate Overlap Events : チェックを外す
- Can Character Step Up On : No
- コリジョンプリセット : NoCollision
- Rendering
- Visible : チェックを外す
- トランスフォーム
-
Plane (Static Mesh)
Boxは、BoxMasked-3Dで使用するLocation、Rotation、Boundsに値を渡すために配置。
Planeの上に大きいBoxが乗っていて、Planeを動かすとPlaneの面に沿ってBoxが追従して動いて、マスクされるイメージです。
- SetBoxMask関数を作成
- BoxMaskの位置や回転をマテリアルに反映させるためのSetBoxMask関数を作成します。ノードは以下の通りです。
- Construction Scriptで、SetBoxMask関数を実行します。
- イベントグラフで、TickイベントにSetBoxMask関数をつなげます。
レベルにBPを配置して確認
- レベルにBP_CrossSectionを配置します。
- レベルにBP_CrossSectionPlaneを配置します。
- BPの原点が板の中心ではないので、板が椅子にオーバーラップできる位置、回転値を設定してください。
- BP_CrossSectionPlaneを動かすと、こんな感じで断面を表示できます。