#はじめに
Unreal Engine 4 (以下UE4)での__弾幕__ってどうやるのか、検証した結果をまとめました。
__Niagara初心者__でも分かるように、手順__を細かめに載せていこうと思います。動画での解説__もあります。
似たような情報を見かけなかったので、割といろいろな方の参考になるかもしれません。
#もくじ
はじめに
1. Niagaraとは
2. 実践!Niagaraパーティクル作成
3. Niagara コリジョン
4. Niagara 弾幕の作り方。(規則的な飛ばし方)
5. サンプルデータ
Niagara参考資料
おわりに
#1. Niagaraとは
##1.1. 概要
Niagaraとは、UE4の新しいパーティクルシステムです。
- 2017年 4.18頃から公開され、
- 2020年 4.25で正式リリースされた次世代VFXシステムです。
現在UE4には、Cascade と Niagara の二つのパーティクルシステムがあり、
4.25の正式リリース後は、Niagara を推していくということなので、
これからパーティクルを触るような人は、Niagaraを覚えた方が良いかもしれません。
Cascadeで過去に作ったパーティクルは、
Niagaraにコンバートするプラグインがあるので、
過去に作ったり買ったパーティクルなどが、無駄にはならないようになっています。
(実験的機能ということで、まだ全てがコンバート可能という訳ではなさそうです。)
##1.2. 何が凄いのか
Cascadeで、複雑な事をしようとすると、C++で機能を拡張する必要があったものが、
Niagaraでは、ノード形式で機能の追加編集が可能という点が、特に大きな要素になっています。
次に挙げられるのが、エミッター要素の共有ができる点が、Cascadeとの大きな違いとなります。
他にも凄い要素があるようですが、より詳しくは、以下の動画がとても参考になります。
##1.3. Niagara基本構造
従来の__Cascadeパーティクル(白)__と __NiagaraSystem(赤)__は、同等の扱いだと思っておいていいです。
FXのNiagaraSystem以外の項目は、凝ったことをする時に使う物だと思っておけばいいです。
基本的な機能を使うだけであれば、NiagaraSystemを作れば、Niagaraのパーティクルは作れます。
NiagaraSystem内で、左の青い方が、Niagara Systemで、右のオレンジが、Niagara Emitterです。
エミッターは、右クリックから追加でき、
- Templates(テンプレート) 基本的なパーティクルエミッターが選べます。
- Parents(親) 自作エミッターはここに表示されます。
- Behavior Examples(動作例) 参考例のエミッターが表示されるので、学習時に確認してみましょう。
エミッターを右クリックから、__「Create Asset From This(これからアセットを作成)」__を選ぶと、エミッターが共有可能な状態でデータが作成されます。
※注意 エミッターの追加方法などが、4.26とは少し変わっているので、お気を付けください。
#2. 実践!Niagaraパーティクル作成
UE4 4.27.1 を立ち上げて、__ThirdParsonテンプレート__を選んで開きます。
多くの方が見慣れているところから始めたいと思います。
※注意 Niagaraは高速に開発が進められている為、バージョンが違うと見た目や項目名などが異なる場合があります。
学習する際は、参考にしている資料と同じバージョンで確認することをお勧めします。
##2.1. Niagara System作成
FXフォルダを作り、その中で、右クリック__>「FX」>「Niagara System」__を選択
__New system from selected emitter(s)(選択したエミッタに基づく新しいシステム)__を選択
今回は、__Fountain__を選びます。選択は、__ダブルクリック__か__緑のプラスボタン__からエミッターを追加します。
__「Finish(終了)」__を押すとナイアガラシステムが作成されます。
名前を NS_Test1 にしました。
ダブルクリックをし、開くと
シンプルな噴水パーティクルが確認できると思います。
確認したら、サードパーソンテンプレートのビューポートに戻り、
作成された NS_Test1 をビューポートにドラッグすると、噴水パーティクルが、発生します。
パーティクルをそのまま置くだけであれば、ナイアガラパーティクルを作成して発生させる工程は、これで完了です。
#3. Niagara コリジョン
今回、弾幕を作るにあたっては、コリジョンの扱いが肝になるので、
パーティクルの細かい制御方法より前に、コリジョンの割り当て方法を先に載せます。
##3.1. コリジョン追加
まず、噴水エミッターの__「Particle Update(パーティクル更新)」の右の「+」をクリック
Collisionを選択すると、赤いビックリマークが出るので、「Fix issue(問題を修正)」__をクリック。
これで、ビューポートに戻ってみると、地面に噴水の球がバウンドしていると思います。
赤いビックリマークが何を意味しているのか、気になる方用に翻訳を。
The module has unmet dependencies.
The following post-dependency is not met: SolveForcesAndVelocity;
Move module Collision Before SolveFrocesAndVelocity
Dismiss the issue without fixing (I know what I'm doing)
----↓DeepL翻訳----
このモジュールには、満たされていない依存関係があります。
以下のポスト依存関係が満たされていません。SolveForcesAndVelocity;
モジュールCollisionをSolveFrocesAndVelocityの前に移動します。 「Fix issue(問題を修正)」
修正せずに問題を解除する(自分が何をしているかわかっている)「Dismiss issue(問題を解除する)」
__SolveForcesAndVelocity__モジュールより上にコリジョンがある必要があるという注意書きで、
__「Fix issue(問題を修正)」__のボタンを押したら自動で順序が変更されたという流れです。
##3.2. コリジョンの衝突通知を行う為に必要な設定
__「Parameters(パラメータ)」__タブの
__「User Exposed(公開されたユーザー)」システム設定の「+」__をクリックし __「Object」__を選択
作成された、NewObject の名前を変更して、__BPCallback__とします。
次に、パーティクル更新の右にある__「+」__をクリックし、blue と検索して、
__「Export Particle Data to Blueprint」__を追加
青いビックリマークの注意書きが出てくるので、一応確認しておきます。
Module Usage Note
The setup to export particle data is somewhat complex.
There is an example asset under the Learn tab of the Epic Games Launcher in the Content Examples project which shows how this works and how the connection is made.
Dismiss
----↓DeepL翻訳----
モジュール使用上の注意
パーティクル データをエクスポートするためのセットアップは、やや複雑です。
Epic Games Launcher の [Learn] タブにある [Content Examples] プロジェクトには、この仕組みと接続方法を示すサンプル アセットがあります。
解除
この機能を理解する為には、Content Examples を確認してください。という注意書きです。
青いビックリマークを消したい場合は、Dismissを押します。放っておいても構いません。
Export Particle Data to Blueprint を選択した状態で、右に詳細表示された
Condition To Export Data の__右の下三角__をクリックして、collision と検索をかけ、
「OUTPUT(出力)」 「COLLISION」 Collision Valid を指定します。
これで、何かが衝突した時、このモジュールが反応するという設定になりました。
反応をどこに送るかの設定が
「Callback Handler Parameter」 のタブで、ここに、先ほど作成した、__「BPCallback」__を指定します。
これで、Niagara側の最低限の設定ができました。
##3.3. ActorにNiagaraを呼び出す
コリジョンの衝突の通知を行う為に、__NiagaraSystem__をそのまま置くのではなく、Actor__を用意します。
右クリック__から、「Blueprint Class(ブループリントクラス)」>「Actor」を選び、「BP_Niagara_Test1」 とします。
BP_Niagara_Test1__を__ダブルクリック__で開き、左上の「+ Add Component(+ コンポーネントを追加)」から、「Niagara Particle System」__を選択
追加された__「Niagara」を選び、詳細欄の「Niagara System Asset」に「NS_Test1」__を指定します。
##3.4. コリジョンイベント ブループリント設定
__イベントグラフ画面__で、右クリックから検索__をかけて「Set Niagara Variable (Object)」__のノードを呼び出します。
__「Event BeginPlay」__に繋ぎ
「In Variable Name」 の欄に __「BPCallback」__と打ちます。
__「Object」の項目には、「Self」__を当てます。
次に、__「Class Settings(クラス設定)」を選択した状態で、
「Interfaces(インターフェース)」>「Implemented Interfaces(実装インターフェース)」
の「Add(追加)」__から
「niagara」で検索をかけて、「Niagra Particle Callback Handler」 を選択します。
そこまでできたら、コンパイル 保存 をしてください。
左下の__「Interfaces(インターフェース)」__の欄の、
__「Niagara」>「Receive Particle Data」を右クリック「Implement event(イベントを実装)」__を選び
「Event Receive Particle Data」 を用意します。
そこに__Print String__を繋いで、Hello が呼ばれるか確認します。
レベル上に、直で置いてある__Niagara System__は、__削除__して、作った__ブループリント__を__ドラッグ__します。
__プレイ__をすると、__Hello__が__画面左__に出てくると思います。
これで、Actorに衝突のイベントを送ることが確認できました。
##3.5. プレイヤーにダメージを送る。
デフォルトのコリジョン設定の場合、__World Dynamic__が当たっており、なんでもかんでも衝突判定を取ります。
これをプレイヤーにのみ衝突判定をしたいと思います。
###プロジェクト設定 トレースチャンネル追加
「Project Settings(プロジェクト設定)」
「Engine(エンジン)」>「Collision」>「Trace Channels」 の__「New Trace Channel(新規のトレースチャンネル)」を選択
「Name(名前)」を「EnemyProjectile」
「Default Response(デフォルト応答)」を「Ignore」
にして「Accept(承認)」__を押します。
新しいトレースチャンネルができたので、これを使用していきます。
###コリジョン トレースチャンネルを指定
__「ナイアガラ(NS_Test1)」を開いて「Collision」の「CPU Collision Trace Channel」__に
__「EnemyProjectile」__をセットします。
###プレイヤー側のコリジョン設定
次にプレイヤー側の設定を、__「ThirdPersonCharacter」__を開いて、
__「Mesh」の「Collision Presets(コリジョンプリセット)」を、「Custom」__にして、
__「Trace Pesponses(トレース応答)」の項目の「EnemyProjectile」__をブロックに変更します。
簡易的には、これで、プレイヤーにのみ衝突する状態になっています。
###ダメージ送信処理
あとは、__Niagara__の__Actor__の__ブループリント__で、__Apply Damage__を __GetPlayerPawn__に送り。
__プレイヤー側のブループリント__で、__Event AnyDamage__を組むと、ダメージが送られてきます。
プレイヤー側のコリジョン判定の基本構造の説明は以上です。
##3.6. 衝突した弾を消したい
現状だと、プレイヤーに弾が当たった後、バウンドして複数回プレイヤーに当たる可能性があります。
衝突したら消えるように設定したいと思います。
__「NS_Test1」の「Particle Update(パーティクル更新)」の右の「+」__をクリック
__「Kill」で検索をかけて、「Kill Particles」__を追加。
__「Kill Particles」の右の下三角をクリックし、「Collision」__と検索
__「OUTPUT(出力)」「COLLISION」「Collision Valid」__を選びます。
これで、衝突したら、消えるという処理になります。
##3.7. プレイヤー以外にダメージを与えたい。
敵の弾をプレイヤーに当てるだけであれば、__Trace Channel__を指定するだけでもなんとかなりますが、
不特定多数の相手にダメージを与えるような場合、ダメージの送り先が分からない状態になります。
何と衝突したか、Actorのブループリントで再度トレースしたいと思います。
###ナイアガラ Export Particle Data to Blueprint 設定
まず、__「ナイアガラ(NS_Test1)」__の 「Export Particle Data to Blueprint」 を選択し、
Vector to Send(As Struct Position) 「PARTICLES」「PRECIOUS(前)」「Position」
Vector To Send(As Struct Velocity) 「PARTICLES」「PRECIOUS(前)」「Velocity」
Float To Send(As Struct Size) 「TRANSIENT(一時的)」「CollisionSize」
を指定します。
###アクターでトレース設定
ナイアガラ用の__「Actor(BP_Niagara_Test1)」を開いて、
「Data」から右に引っ張って「For Each Loop」を作り、「Array Element」 を「 Break」__で展開し、
「Position」と「Size」と「Velocity」を使って、「SphereTraceByChannel」 にセットします。
Trace結果の__Hit Actor__を__Apply Damage__に当てることが可能です。
これで、不特定多数の衝突物にダメージを送る処理ができました。
※注意 方法論の一つです。より良い方法がありましたら、共有していただけると嬉しいです。
##3.8. 衝突した場所にパーティクルを発生させたい。
衝突エフェクトを出したい場合の設定方法も載せておこうと思います。
###Generate Collision Event
コリジョンが発生したイベントを、別のエミッターに送る時に使います。
このモジュールを追加すると、赤いビックリマークの注意文が出てきます。
Niagara Logをチェックすると
Before the Particles.ID parameter can be used, the 'Requires persistent IDs' option has to be activated in the emitter properties. Note that this comes with additional memory and CPU costs. - Fountain, Particle Update Script,
----↓DeepL翻訳----
Particles.IDパラメータを使用するには、エミッターのプロパティで「Requires persistent IDs」オプションを有効にする必要があります。これには追加のメモリとCPUコストがかかることに注意してください。- Fountain, Particle Update Script,
パーティクルIDを有効にする必要があることと、少し重くなるけどいいかという確認です。
###Requires Parsistent IDs
Requires Parsistent IDs のチェックを入れると、赤いビックリマークと注意文が消えます。
###新規エミッターを追加
右クリックからエミッターを追加で、Fountainを選びます。
別のエミッターでも構いませんが、知らないエミッターを追加するより混乱が少ないので、これを選びます。
###Event Handler Properties
__イベントハンドラー__の__プラス__を__クリック__すると、プロパティが追加されるので、
Source を CollisionEvent
Spawn Number を 30(衝突時に発生するパーティクルの数)
にします。
###Receive Collision Event
もう一度イベントハンドラーの右のプラスをクリックして、collisionと検索。
Receive Collision Event を追加します。
これで、衝突が起こった場所にパーティクルが発生するようになりました。
###Spawn Rate を削除
Spawn Rate があると衝突以外の場所にもパーティクルが発生する為、Spawn Rateを削除します。
画像は、チェックを外しているだけですが、右クリックから削除してもいいです。
###衝突チェック
パーティクルの色を赤くして、衝突後のパーティクルと分かりやすくしています。
見た目的には、Velocityの調整や、パーティクルサイズなどの調整が必要だと思いますが、
イベントハンドラーを使った衝突位置にパーティクルを発生させる手順は以上です。
#4. Niagara 弾幕の作り方(規則的な飛ばし方)
新しいNiagaraSystemを作成します。
構造を把握するために、Emptyを選んで、NS_Test2 を作成します。
##4.1. パーティクルスポーン設定
###Spawn Burst Instantaneous
Emptyは空のエミッターなので、まずパーティクルを発生させるSpawnモジュールを追加します。
Spawn Burst Instantaneous
このモジュールを使うと、最初のフレームで、指定位置に指定数のパーティクルが発生します。
__Spawn Count__を仮に__32__にしておきます。この時点では、エミッターの中央位置に一つ点が見える状態ですが、
32個のパーティクルが重なって表示されています。
ここから、規則的な位置にパーティクルを配置します。
##4.2. 規則的にパーティクルを並べる。
Locationモジュールを追加することで、パーティクルの発生位置を調整することができます。
規則的な配列がしやすいモジュールをいくつかピックアップします。
###Sphere Location
球状に配列する時に便利。
Sphere Distribution を Uniform にして
デフォルトの状態が、正多角形の頂点の位置にパーティクルが発生します。
Uniform Spiral Amount の値を変えると、配列のパターンを変えることができます。
他の数値を変えると、もっといろいろなバリエーションが作れます。
###Grid Location
四角いグリッド状に綺麗に配列する時に便利。
Grid Locationを追加すると、Spawn Particles in Grid が作られるので、こちらで、パーティクルの数を調整。
Grid Locationの方で、間隔などの調整ができます。
###Torus Location
リング状に配列する時に便利。
使い道が多そうなのですが、結構設定いじらないと綺麗に並んでくれないので、
画像を参考に設定をいじってみてください。
###自作モジュールを作るには
各モジュールを、ダブルクリックすると、構造が見ることができるので、
やりたいことに近いモジュールの中身を確認して、自分で、モジュールを作成することができます。
標準で用意してあるモジュールで、足りないものは、自分で作る事ができます。
##4.3. 規則的にパーティクルを飛ばす。
規則的な配置が済んで、簡単に飛ばす場合は、
###Emitter State
まず__Emitter State__を、System から __Self__に変更します。
Loop Duration を __0.1__にします。(0.1秒ごとにパーティクルが発生するようになります。)
Add Velocity from Point
Add Velocity from Pointを使うと、中心から一定の速度でパーティクルを移動させることができます。
Add Velocity from Point を追加すると、注意文が出てくるので読みます。
The module has unmet dependencies.
The follow post-dependency is not met: SolveForcesVelocity;
Add new dependency module SoleceForcesAndVelocity Fix issue
Add new dependincy module ApplyInitialForces Fix issue
Dismiss the issue without fixing (I know what I'm doing) Dismiss issue
----↓DeepL翻訳----
このモジュールには、満たされていない依存関係があります。
フォローポストの依存関係が満たされていません。SolveForcesVelocity;
新しい依存モジュールSoleceForcesAndVelocityの追加 問題の修正
新しい依存モジュール ApplyInitialForces の追加 問題の修正
修正せずに問題を却下する(自分が何をしているかわかっている) 問題の解除
SolveForcesVelocityが必要ですということで、問題を修正するを押すと、
SolveForcesVelocityが自動で作成されます。
Velocity Strength(速度設定)は、好きな数値で大丈夫です。
規則的に飛ばす基本は以上です。
Expression
Expression という数式を直接打って、制御する方法があり、
モジュールやスクリプトを作成するほどでもないものは、Expressionを活用することで、数字を打つだけでは出来ない挙動が、作成できます。
簡単な__Expression__で、エミッターを回転させたいと思います。
Torus Location の Normalized Angle Around Torus Axis の右の__下三角__をクリックして、
__New Expression__を選びます。
試しに ((Emitter.Age)*0.1)
と打ってみます。
これだけで、エミッターが回転するようになります。
(Emitter.Age)
に何かを掛けると、時間に応じて変化のある値を簡単に作れるので、重宝します。
この記事と同時に投稿される動画や、Githubにサンプルプロジェクトを置いておくので、
そちらも確認してみていただければと思います。
機能別サンプルで使われていたExpressionの抜粋 こんな組み方もあるみたい。
Sin(Emitter.Age)*56
normalize(((( rand(float3(1.0,1.0,1.0) ))) * 2 ) -1 )
rand(1.5f) + 2.2f
Emitter.InitialPosition + Particles.RandomVector *rand(145.0f)
cross(Particles.RandomVector, float3(0,8,0)) * (float3(0.0f, 0.0f, Emitter.ZOffset) *0.2f) + (-1.0f * normalize(Emitter.InitialPosition - Particles.Position)*20)
Particles.NormalizedAge < 0.333 ? float4(1,0.1,0.1,1) : Particles.NormalizedAge < 0.575 ? float4(0.1,1,0.1,1) : float4(0.1,0.1,1,1)
Particles.Position + float3(0, 0, ( sin(Engine.Time) * 0.3f ))
(1.0f - abs(Particles.NormalizedAge * 2.0f -1.0f)) * 2.0f
1-Particles.RandomVector * (length(Particles.Position - Emitter.InitialPosition)*0.25)
Particles.Position.z > Emitter.InitialPosition.z - Emitter.ZOffset ? Particles.Position : float3(Particles.Position.x, Particles.Position.y, Emitter.InitialPosition.z -Emitter.ZOffset)
この辺、情報共有していけると、より便利な世の中になりそうですね。
#5. サンプルデータ
ナイアガラで弾幕を作る際に参考になると思う要点を、サンプルデータに並べてみました。
ダウンロード↓
中級者以上の方は、データを見るだけで理解できると思いますが、
Niagara初心者の方は、この記事を把握するか、__動画の解説__を見た上で触った方が理解しやすいかなと思います。
#Niagara参考資料
##機能別サンプル(Content Examples)
__Epicランチャー__からラーニングのタブを選んで、機能別サンプルを選んで、プロジェクトを作成すると、
UnrealEngineのさまざまな機能を確認できます。
今回見るべきなのは、Maps の中の Niagara と Niagara_Advanced の二つです。
二つとも自分で確認して、興味があるものの中身を確認していけばいいのですが、
今回関連がある要素を抜粋します。
##Niagara 2.5 Expressions
Expressionでどういう処理ができるのかを確認できます。
##Niagara_Advenced 2.1 Particle Attribute Reader
リング状に配列する方法は、ここから拝借しました。
また、記事では紹介していませんが、Particle Attribute Reader は、
少し凝った事をする時には、必要になる機能だと思うので、凝ったことをする人は、要チェックです。
##Niagara_Advenced 4.2 Export Particle Data to Blueprint
コリジョン情報を、アクターに送る工程は、こちらがベースになっています。
公式の情報を確認したい場合は、こちらをご確認ください。
他にもいろいろあるので、確認してみましょう。
##花火ナイアガラサンプル(まめお様)
花火を作る際に参考になると思います。
##参考リンク
-
Creating next-gen visual effects that think for themselves with Niagara | Unreal Engine 5
-
Building Effects with Niagara and Blueprint | GDC 2019 | Unreal Engine
-
An Introduction To Niagara | Feature Highlight | Unreal Engine Livestream
-
Diving Into Niagara: Intelligent Particle Effects | Unreal Fest Online 2020
-
Programmable VFX with Unreal Engine's Niagara | GDC 2018 | Unreal Engine
-
Introduction to Niagara | Unreal Fest Europe 2019 | Unreal Engine
-
The Evolution of Real-Time VFX with Unreal Engine's Niagara | Unreal Fest Online 2020
-
Introduction to the Niagara Visual Effects System | 2018 EDU Summit | Unreal Engine
-
NVIDIA Studio | YouTube | UnrealEngineパート1のナイアガラ入門| NVIDIAスタジオセッション
書き加えた方が良いリンクがありましたら、コメントいただけると助かります。
- この記事関連リンクとしては、
- YouTube【15分で解説】UE4で弾幕ゲームを作る際に、押さえておきたい Niagara Collision の扱い方。
- YouTube【English】 How to use Niagara Collision when creating a bullet hell game in UE4.
- GitHub NiagaraSample
#おわりに
弾幕ゲームの作り方の質問を受けて、
Niagara使えば、簡単に弾幕作れるんじゃないかと、軽い気持ちで調べたんですが、
コリジョン周りの情報が少なく困りました。
また、旧バージョンで情報共有していただけている部分などは、
使えなくなっているものや、名称が変わっているものなどがあり、
Niagaraの情報を探るのは、想定以上に大変でした。
そんなこんなで、Niagara初心者でも分かるようにしようと、つらつら書いていったら、
ずいぶん縦に長い記事になってしまいました。
良い感じに情報共有をして、ある程度の事は、誰でも簡単に出来るようにしていきたいですね。
結構時間をかけて調べたものの、
今のところ、弾幕ゲームを作る予定が無いのが、悲しいところです。
ツイッターのフォローとか、チャンネル登録とかしてもらえると励みになります。