この記事では、Niagara エディターと Cascade エディターで、それぞれ NiagaraSystem と ParticleSystem 特殊効果のエミッターにモジュールを自動的に追加する方法を記録します。目的は、アート (またはプログラム) に必要なモジュールをバッチ処理して自動的に追加し、アートの作成を容易にすることです。普遍的な効果を作成するためのプログラムと、普遍的な効果を作成するためのプログラム。
1. 背景
Particle と Cascade (ParticleSystem エディタの名前) に関する関連知識と用語については、次を参照してください: ParticleSystem
Niagara エディタと Cascade は類似した構造を持っているように見えますが、実際にははるかに複雑です。一般的な構造は次の図に示すとおりです。
これらはすべてParameters -> Modules -> Emitters -> System
4 層構造であり、その中には次のようなものがあります。
- システム - 特殊効果リソース全体を指します。
- エミッタ - 各エミッタ (スプライト、メッシュ、リボンなどのパーティクルの放出を制御します)、エディタ内の垂直バー全体を指します。
- モジュール - エミッタのさまざまなプロパティと機能を制御する各モジュールを指しますエディタ内の各水平バー
- パラメータ - 各モジュールのパラメータを指します。アーティストが設定したり、プログラム内のプログラムによって制御したりできます。
で:
- システム - 実行時にコンポーネントになります。ParticleSystem によって作成され
UParticleSystemComponent
、NiagaraSystem によって作成されます。UNiagaraComponent
UParticleEmitter
エミッタ-静的時とUNiagaraEmitter
実行時FParticleMeshEmitterInstance
FNiagaraEmitterInstance
- モジュール - パーティクルはすべてハードコーディングされており、
Engine\Source\Runtime\Engine\Classes\Particles
フォルダー内にあります。使用できるタイプは限られています (図の ColorOverLife コードなど)。UParticleModuleColorOverLife
ナイアガラはアセットであり、設計図と見なすことができ、エンジンに付属しています。これらはすべてEngine\Plugins\FX\Niagara\Content\Modules
ディレクトリ内にあります。もちろん、自分で接続して、自分のプロジェクトのアセットとして使用することもできます。非常に柔軟で使いやすいです。 - パラメータ - 設定可能なパラメータ、カスケードも固定です 外部に公開しブループリントやプログラムで設定する場合は下図のようにパラメータに設定可能 ブループリントやコードはこんな感じで制御可能; Niagaraにパラメータを追加して、そのパラメータを使用したい入力に関連付けてから、それを外部から制御する必要があります (外部から設定できるのは User Expoosed パラメータのみですが、これは非常に不快です = =
SetVectorParameter("ABC", DummyVec);
)UserExposed
2. 具体的な方法
両方の特殊効果のモジュールを自動的に追加するための前提条件は、コンテンツ ブラウザで開くか複数選択するか、保存時にトリガーするか、ボタンで均一に実行するかに関係なく、特殊効果リソースをコード内で取得できることです (ナイアガラはそうでない場合もあります)。これを行うには、エディターを開く必要があります)。
2.1 パーティクルシステム
右クリックして Cascade にエミッタを追加するときにコードを参照してください。Lifeなどのvoid FCascade::OnNewEmitter()
いくつかのデフォルト モジュール ( UParticleSpriteEmitter::SetToSensibleDefaults()
) が自動的に追加されます。エンジンをコピーするだけです。
// Lifetime module
UParticleModuleLifetime* LifetimeModule = NewObject<UParticleModuleLifetime>(GetOuter());
UDistributionFloatUniform* LifetimeDist = Cast<UDistributionFloatUniform>(LifetimeModule->Lifetime.Distribution);
if (LifetimeDist)
{
LifetimeDist->Min = 1.0f;
LifetimeDist->Max = 1.0f;
LifetimeDist->bIsDirty = true;
}
LifetimeModule->LODValidity = 1;
LODLevel->Modules.Add(LifetimeModule);
エンジンに付属するモジュールの代わりにカスタム モジュールを追加する場合は、エンジンの記述メソッドをコピーして、自分でコードにモジュールを追加する必要がありますが、これは非常に簡単です。::InitializeDefaults()
ここでは、外部制御可能なパラメータを追加するなど、デフォルト値を直接設定できますNewObject<UDistributionFloatParticleParameter>(
。
一部の構造は追加されて開かれないことに注意してくださいENGINE_API
。たとえばFComposableFloatDistribution
、それらを使用する必要がある場合は、自分で追加する必要があります。
2.2 ナイアガラシステム
Niagara はもう少し複雑で、階層は次のとおりです。
- FNiagaraSystemViewModel - エディターの全体的な効果
- FNiagaraEmitterHandleViewModel - エディター内のすべてのエミッター
- UNIagaraStackViewModel - 各エミッターのスタック (モジュールのスタック)
- UNIagaraStackItemGroup - 各グループ (下図に示すように、合計 7 つ)
- UNIagaraStackModuleItem - 各モジュールは、
エディター内の 7 つの暗いボックスとその下の明るいボックスで表されるグループに対応します。
具体的な方法のリファレンスvoid UNiagaraEmitterConversionContext::InternalFinalizeStackEntryAddActions()
FNiagaraEditorModule& NiagaraEditorModule = FModuleManager::GetModuleChecked<FNiagaraEditorModule>("NiagaraEditor");
TSharedPtr<FNiagaraSystemViewModel> const SystemViewModel = NiagaraEditorModule.GetExistingViewModelForSystem(NS);
if (!SystemViewModel.IsValid())
{
return;
}
const TArray<TSharedRef<FNiagaraEmitterHandleViewModel>>& EmitterViewModels = SystemViewModel->GetEmitterHandleViewModels();
// 每一个发射器
for (TSharedRef<FNiagaraEmitterHandleViewModel> EmitterHandleViewModel : EmitterViewModels)
{
UNiagaraStackViewModel* StackViewModel = EmitterHandleViewModel->GetEmitterStackViewModel();
TArray<UNiagaraStackItemGroup*> StackItemGroups;
StackViewModel->GetRootEntry()->GetUnfilteredChildrenOfType<UNiagaraStackItemGroup>(StackItemGroups);
// 每一个 StackItemGroup
for (UNiagaraStackItemGroup* StackItemGroup : StackItemGroups)
{
// 筛选出 ParticleSpawn Stack
FName const ExecutionCategoryName = StackItemGroup->GetExecutionCategoryName();
if (ExecutionCategoryName != UNiagaraStackEntry::FExecutionCategoryNames::Particle)
{
continue;
}
FName const ExecutionSubcategoryName = StackItemGroup->GetExecutionSubcategoryName();
if (ExecutionSubcategoryName != UNiagaraStackEntry::FExecutionSubcategoryNames::Spawn)
{
continue;
}
// 自动添加一个预设 Module
UNiagaraClipboardContent* const ClipboardContent = UNiagaraClipboardContent::Create();
UNiagaraScript* const Script = LoadObject<UNiagaraScript>(nullptr, TEXT("/Game/Effects/NiagaraModules/Test.Test"), nullptr, LOAD_None, nullptr);
const UNiagaraClipboardFunction* const ClipboardFunction = UNiagaraClipboardFunction::CreateScriptFunction(ClipboardContent, "NS_ScaleSizeBySystem", Script, FGuid());
ClipboardContent->Functions.Add(ClipboardFunction);
// Commit the clipboard content to the target stack entry
FText PasteWarning = FText();
StackItemGroup->Paste(ClipboardContent, PasteWarning);
}
}
SNiagaraStackFunctionInputValue::OnFunctionInputDrop
新しく追加したモジュールに入力があり、パラメータを関連付ける必要がある場合は、この関数 を参照できます。これは、パラメータを入力ピンにドラッグする関数です。直接設定したい場合は、直接設定できます。FunctionInput->SetLinkedValueHandle(Handle);