Gaming Life

一日24時間、ゲームは10時間

UE4 Niagaraを触ってみる(3) 引き寄せ(Repeller)モジュールを自作

 シリーズNiagara第三弾。前回記事はこちら。

ai-gaminglife.hatenablog.com

 前回、パーティクルを引き寄せるアトラクタを作った。今回はその逆。パーティクルを払いのけるような動きをする「リペラー(Repeller)」モジュールを作成した。

完成品

環境

UE4.20 preview5

参考にしたサイト

 Nature of Code -Processingで始める自然現象のシミュレーション- のp148以降に紹介されているアルゴリズムを流用。

Nature of Code -Processingではじめる自然現象のシミュレーション-

Nature of Code -Processingではじめる自然現象のシミュレーション-

 こちらの本は英語版が無料で公開されており、全ソースコードGitHubで公開されている。

 今回流用したアルゴリズムのProcessingソースコードこちら

Module Scriptの概要

全体図

f:id:ai_gaminglife:20180714121125p:plain

 万有引力公式で得られるベクトルに-1を乗じることで反発方向への速度ベクトルを取得している。

解説

f:id:ai_gaminglife:20180714121136p:plain

 Map Getで Partice.PositionとPartice.Velocityを取得。Particle.○○は各パーティクルが持つ変数のこと。

 続いてMap GetのModule -> Make New、もしくはParametersパネルのModuleから

  • Module.RepellerPoint
  • Module.DistMin
  • Module.DistMax
  • Module.Strength

を追加する。Module.○○はそのモジュールの中だけで使えるローカル変数で、エミッター編集画面で編集することが出来る。

 Module.RepellerPoint - Particle.Positionで反発点とパーティクルとの間のベクトルを取得できる。このベクトルをNormalize(正規化、長さ1のベクトルに変える)、Length(ベクトルの長さを取得)につないでおく。

f:id:ai_gaminglife:20180714121145p:plain

 反発点とパーティクルの間の距離を万有引力公式の距離に当たる部分に突っ込めば反発力が得られる。が、例えばRepellerPointと全く同じ位置にパーティクルが生成されるとそのパーティクルはずっと動かなくなり、RepellerPointとかなり離れた位置に生成されると、その距離の二乗で割ったものがパーティクルにかかる力となる都合上、殆ど動きがなくなってしまう。

 この問題を解決するため、反発点・パーティクル間の距離をある範囲に制限(Clamp)する。ClampのMinにはModule.DistMinを、MaxにはModule.DistMaxを使用する。

f:id:ai_gaminglife:20180714121154p:plain

 万有引力公式を使って得た力を反発点・パーティクル間ベクトルを正規化したものに乗じる。これは運動方程式に従うと、ある時刻での加速度に当たることがわかる。

 加速度がわかればあとはパーティクルの速度を更新するだけ。得られた加速度をParticle.Velocityに加え、Map Setで更新する。

 これで完成。ちなみに冒頭紹介した動画は、前回記事のもののアトラクタモジュールをリペラーモジュールに差し替えただけで、そのパラメータは

  • DistMax 100.0
  • DistMin 10.0
  • RepellerPoint 0.0, 0.0, 0.0
  • Strength 20000

に設定している。

あとがき

 引き寄せが作れたから反発を実装してやろうと軽い気持ちでつくったものだが超エモいエフェクトが出来た。Niagara、本当に面白い。