げーむ開発徒然日記~怠惰のために勤勉~

Unreal Engineや3DCG制作について学んだことを記事にしていきます

第16回UE4ぷちコン振り返り その②~画面上にペイントする~

f:id:raksul_01:20210921175136p:plain

今回は、第16回UE4ぷちコンで実装した画面上へのペイントシステムをどのように実装したかなどを紹介したいと思います。

 

★目次★

 

概要

作るもののイメージはこちら↓

マウスの左ボタンを押している間は黒いインクが塗れるようなものになっています。

さて、やり方としてはUE4を触っている方であれば

TextureRenderTarget2D(以下、TRT2D)を用意し、ウィジェットに描画。マウス座標に応じてDraw TextureあるいはDraw Materialを極短い間隔(Tickなど)で使用することによってTRT2Dに対して疑似的にペイント。

といった方法が通常は思いつくかなと思います。

しかし、今回は少し違ったアプローチで実装してみました。というのも、上記の動画をご覧の通り、インクが滲んで広がるような表現をしたかったためです(大神の筆しらべもよく見ると広がっていますね)。

※上述したような通常の方法で、DrawTextureを用いて同じ座標にサイズを徐々に上げたテクスチャを描画するような手法を使ってみたところ、TRT2Dの更新頻度が上がって負荷が半端なくなりました(当然そうなるのはわかっていたことですが)。

また、以下の前回記事で紹介した、大神の筆しらべをUnityで再現したものUE4で言うTRT2Dのようなものを使用しており、インクが広がるような表現までは再現していませんでした

要約

使用したUE4のバージョンは4.26となります。

今回のアプローチを簡単にまとめると、

  • ウィジェット上にNiagaraエミッタをマウス座標にフレーム毎に更新
  • 当該Niagaraエミッタからスプライトパーティクル(TRT2Dを使用するやり方で描画するTextureの代わり)をスポーン

という手法になります。

Niagaraパーティクルをウィジェットに描画するにあたって、下記のプラグインを使用しました。無料です。

 使い方はプラグイン制作者様のチュートリアルを見た方が早いので、本記事では割愛します。

実装方法

ナイアガラシステムの準備

それでは実装方法に入りますが、UE4(特にウィジェットブループリント)の基礎知識があるものとして細かいところは省略しつつ進めます。

本記事の真似をするだけではできないかもしれませんのでご容赦ください。また、名付けは適当なので任意でお願いします。

まずは、ナイアガラシステムNS_Brushを作成します。エミッタとしてSimpleSpriteBurstを追加しておくとやりやすいと思います。

f:id:raksul_01:20210921185717p:plain

今回、最低限下記のエミッタ設定を行いました。

  • Emitter StateのLife Cycle ModeをSelf, Loop BehaviorをInfinite
    →パーティクルのスポーンが止まらないように
  • Particle StateのKill Particles When Lifetime Has Elapsedのチェックを外す
    →パーティクルが消えないように
  • Spawn Rateを750以上
  • パーティクル更新にScale Sprite Sizeを追加して、1秒で1.2倍くらいのサイズになるようScale Vector 2DBy Curveを設定

あとはスプライトに適用するマテリアルですが、以下のような適当なものを用意しました。

f:id:raksul_01:20210921191908p:plain

ナイアガラエディタでのプレビュー用マテリアル(M_BrushParticle)

これは、あくまでもナイアガラエディタ上でプレビューするためのマテリアルです。

使用しているプラグインNiagara UI Rendererの都合上、マテリアルドメインUser Interfaceにしたマテリアルも別途用意しておいてください。

結局、応募作品もこの雑なマテリアルのままにしてしまいました。

f:id:raksul_01:20210921192015p:plain
後述するNiagara System Widgetで使うマテリアル(M_BrushParticleUI)

ウィジェットの準備

キャンバス用に新規ウィジェットWB_TestCanvasを作成し、パレットからNiagara System Widgetを追加します(NS_BrushInkと名付けました)。

また、Borderを最上層に追加します(試したところ、これがないと後のOn Mouse Button Downなどが動作しないみたいです)。

f:id:raksul_01:20210921184916p:plain
f:id:raksul_01:20210921210629p:plain

そして、NS_BrushInkを選択した状態で詳細タブから以下のように設定します(マテリアルの名前が誤字ってますが気にしないでください)。

f:id:raksul_01:20210921192728p:plain

Material Remap Listはナイアガラエディタでスプライトに適用していたM_BrushParticle(左)をウィジェットへの描画用にM_BrushParticleUI(右)に置換する設定です。

また、Auto Activateのチェックを外さないとマウスのボタンを押してなくても常に描かれてしまいますので外しておきます。

次に、On Mouse Button Down関数をオーバーライドして以下のようにノードを組みます。

f:id:raksul_01:20210921193231p:plain

変数PointsVector 2Dの配列で、今回は使いませんが後に「描いた線に沿った道の生成」の紹介記事で使うことになります。

ちなみにこの処理は、左ボタンを押したポイントのみにインクを塗るためのものであり、このまま連続して線を描くときには次に説明する処理が必要となります。

この処理のために、次はOn Mouse Move関数をオーバーライドして以下のようにノードを組みます。

f:id:raksul_01:20210921194005p:plain

始めの部分でエミッタの位置をカーソル位置に更新しています。

f:id:raksul_01:20210921194140p:plain

マウス位置にエミッタ位置を更新

その後のブランチ処理は、左ボタン押下状態かつマウスが一定距離移動した場合にのみナイアガラシステムをアクティベートするものです。これがないとエミッタの設定上、カーソルを動かさなくても同じ場所に永遠にパーティクルがスポーンされ続けてしまいPCが爆発します

f:id:raksul_01:20210921194502p:plain
マウスが一定距離移動したらナイアガラシステムをアクティベート

最後の処理(拡大画像無し)は、先ほどと同様、Pointsにアイテムを追加するものです。

ポーンの用意

適当なポーンを用意して、インプットアクションやキー入力でWB_TestCanvasをビューポートに表示する処理を追加します。

また、必要に応じてSet Show Mouse CursorやSet Input Mode Game And UIなども入れる必要もあります。

f:id:raksul_01:20210921211429p:plain

※上記のようなFlip Flopの使用はバグの元となりやすいため推奨しません。真面目に作るならbool値を使いましょう。

---セットアップ完了!---

上手くいけば、Hキーを押せばペイントできるようになり、再びHキーを押すことでキャンバスが排除されるようなシステムができているはずです。

最後に

  • 実際の応募作品ではBPC_MagicBrushというコンポーネントウィジェット作成だとかスペシャルスキルだとかほとんどの機能を入れて、どのポーンに対してもペイント&道生成&スキルを簡単に実装できるようにしていました。
    f:id:raksul_01:20210921212107p:plain
    絵筆の機能をまとめてコンポーネント化したもの

以上、間違いなどがあればDMやコメント等で教えてください!