LoginSignup
2
2

More than 3 years have passed since last update.

UE4 パーティクルシステムについてのメモ

Posted at

概要

UnrealEngine の ParticleSystem についてのメモです。

環境

Windows10
Visual Studio 2017
UnrealEngine 4.25

参考

以下を参考にさせて頂きました、ありがとうございます。

UE公式 : パーティクル システムのリファレンス
【UE4】Particle Instance Parameter について(解説)

関連ソース

"Engine\Source\Runtime\Engine\Classes\Particles\ParticleSystem.h"
"Engine\Source\Runtime\Engine\Classes\Particles\ParticleSystemComponent.h"

パーティクルを発生させる

コンポーネントを作成してパーティクルを指定する

パーティクルアセットの指定やアタッチ座標等を全て指定する必要があります。
AttachToComponent で指定したコンポーネントにアタッチされます。

SpawnEffect0.jpg

作成済のパーティクルシステムコンポーネントに対して発生させる

パーティクルを指定してから明示的に発生させます。コンポーネントがアクティベートしていない場合は、Acticateノードも繋ぐ必要があります。
発生位置などは一緒で、条件によってパーティクルアセットが違う場合にはこの方法がよいと思われます。

SpawnEffect1.jpg

パーティクルアセットをドロップする

ブループリントのイベントグラフにパーティクルアセットをドロップするとそのままコンポーネント追加ノードが作成されます。ルートコンポーネント以下にアタッチされるようです。
パーティクル1個で、アセットも決まっているような生成などはこれが一番楽です。

DirectAsset.jpg

C++での制御について

パーティクルシステムコンポーネントを生成する

ATestActor.h
UCLASS()
class TEST_API ATestActor : public AActor
{
    GENERATED_BODY()

    // コンストラクタ
    ATestActor(const FObjectInitializer& ObjectInitializer);

    // ..省略..

    // シーンコンポーネント
    UPROPERTY(Category = "Test", VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    class USceneComponent*      SceneComponent;

    // パーティクルシステムコンポーネント
    UPROPERTY(Category = "Test", VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    class UParticleSystemComponent* PSC;
};

ATestActor.cpp

// コンストラクタ
ATestActor::ATestActor(const FObjectInitializer& ObjectInitializer)
{
    // シーンコンポーネント作成
    SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent0"));
    if( SceneComponent ){
        RootComponent = SceneComponent;
    }

    // パーティクルシステムコンポーネント作成
    PSC = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleSystemComponent0"));
    if(PSC){
        PSC->SetupAttachment(RootComponent);
        PSC->SecondsBeforeInactive = 1.0f;
        PSC->bAutoActivate = false;
    }
}

エフェクトを発生させる

コンストラクタでパーティクルアセットを取得後、任意のタイミングでパーティクルを発生させます。パーティクルシステムコンポーネントを作成する場合と、予め作成済のパーティクルシステムコンポーネントを使う場合です。
以下コード例。

ATestActor.h
UCLASS()
class TEST_API ATestActor : public AActor
{
    GENERATED_BODY()

    // 省略..

    // パーティクル
    class UParticleSystem* Particle;
};
ATestActor.cpp
#include "ATestActor.h"
#include "Engine.h"
#include "ParticleHelper.h"
#include "Particles/ParticleSystem.h"
#include "Particles/ParticleSystemComponent.h"  
#include "Runtime/CoreUObject/Public/UObject/ConstructorHelpers.h"

// コンストラクタ
ATestActor::ATestActor(const FObjectInitializer& ObjectInitializer)
{
    // パーティクルアセットを探す
    ConstructorHelpers::FObjectFinder< UParticleSystem > find_eff(TEXT("ParticleSystem'/Game/Particles/P_Fire.P_Fire'"));
    if (find_eff.Succeeded()) {
        Particle = find_eff.Object;
    }
}

void ATestActor::BeginPlay()
{
    Super::BeginPlay();

    // 作成例1
    // コンポーネントを作成してパーティクルを設定し発生させる
    UParticleSystemComponent* _PSC = UGameplayStatics::SpawnEmitterAttached(Particle, RootComponent, NAME_None, FVector(0.0f, 0.0f, 0.0f), FRotator(0.0f, 0.0f, 0.0f));


    // 作成例2
    // 作成済パーティクルシステムコンポーネント(PSC)に対して発生させる
    if(PSC){
        // アクティベート
        PSC->Activate();
        // パーティクルを設定
        PSC->SetTemplate(Particle);
        // エミッタを有効に
        PSC->SetEmitterEnable(NAME_None, true);
    }

}

備考

GameplayStaticsに用意されているメソッドは以下の様になっています。

GameplayStatics.h

// スケール指定なしのC++用SpawnEmitterAtLocation下位互換バージョン
static UParticleSystemComponent* SpawnEmitterAtLocation(const UObject* WorldContextObject, UParticleSystem* EmitterTemplate, FVector Location, FRotator Rotation, bool bAutoDestroy, EPSCPoolMethod PoolingMethod = EPSCPoolMethod::None, bool bAutoActivateSystem =true);

// 指定された位置と回転で指定されたエフェクトを再生します。 エフェクトが完了するとシステムは消えます。 複製しません。
static UParticleSystemComponent* SpawnEmitterAtLocation(UWorld* World, UParticleSystem* EmitterTemplate, const FTransform& SpawnTransform, bool bAutoDestroy = true, EPSCPoolMethod PoolingMethod = EPSCPoolMethod::None, bool bAutoActivate = true);

// スケール指定なしのC++用SpawnEmitterAttached 下位互換バージョン
static UParticleSystemComponent* SpawnEmitterAttached(class UParticleSystem* EmitterTemplate, class USceneComponent* AttachToComponent, FName AttachPointName, FVector Location, FRotator Rotation, EAttachLocation::Type LocationType, bool bAutoDestroy = true, EPSCPoolMethod PoolingMethod = EPSCPoolMethod::None, bool bAutoActivate=true);

Particle Instance Parameter でパーティクルカラー変更テスト

準備

パーティクルエミッタにモジュールを追加する
[右クリック] -> [Color] -> [Scalar Color / Life]

Add_Module.jpg

以下の様に追加されます。
Add_ScaleColorLife.jpg

詳細設定を変更する
DistributionDistribution Vector Particle Parameter に変更する
Parameter Name にパラメータ名前を入れる
Param Modes を各 DPM Direct に変更する

Detail.jpg

パーティクルシステムコンポーネントの詳細でパラメータを公開する
エミッタアクションの パラメータを公開 でパーティクルのパラメータを反映させる
ParamTypeColor にする

PSC_Detail.jpg

実行テスト

以下のようなBPで実行テストを行います。
キー[1]押下でパーティクルを発生させて、キー[2]でそのパーティクルのパラメータ TestParam のカラーパラメータを変更することができます。

sample_BP.jpg

発生時は青のパーティクルですが、パラメータを適用すると黄色に変化します。

備考

C++で同様にパラメータを変化させることもできます。
以下コード例

.cpp
    // パーティクルシステムコンポーネントPSCに適用されている TestParam というパラメータにカラー値を入れる
    PSC->SetColorParameter(FName("TestParam"), FLinearColor(0.0f, 1.0f, 1.0f));

エンジンコードを見ると他にインスタンスパラメータを取得できるメソッドが確認できます。インスタンスパラメータの ParamType に対応しているようです。

ParticleSystemComponent.h
// Float型パラメータ
UFUNCTION(BlueprintCallable, Category="Effects|Components|ParticleSystem")
virtual void SetFloatParameter(FName ParameterName, float Param) {}

// Vector型パラメータ
UFUNCTION(BlueprintCallable, Category="Effects|Components|ParticleSystem")
virtual void SetVectorParameter(FName ParameterName, FVector Param) {}

// Color型パラメータ
UFUNCTION(BlueprintCallable, Category="Effects|Components|ParticleSystem")
virtual void SetColorParameter(FName ParameterName, FLinearColor Param) {}

// Actor型パラメータ
UFUNCTION(BlueprintCallable, Category="Effects|Components|ParticleSystem")
virtual void SetActorParameter(FName ParameterName, class AActor* Param) {}

// Material型パラメータ
UFUNCTION(BlueprintCallable, Category="Effects|Components|ParticleSystem")
void SetMaterialParameter(FName ParameterName, class UMaterialInterface* Param);

パーティクルのパフォーマンス設定について

パーティクルのパフォーマンス設定
performance.jpg

C++

.cpp
// エミッタの重要度の変更
PSC->Template->MaxSignificanceLevel = EParticleSignificanceLevel::Low;

// Tickの最小時間の変更(66msec = 15FPS)
PSC->Template->MinTimeBetweenTicks = 66;

適正な設定をすることで処理負荷軽減が期待できます。
可能なら動的な設定をするとよりよいかもしれません。
Max Significance Level はカリングの優先度を決めるパラメータのようです。

まとめ

パーティクル制御のためのメモ書きなのでまとまりがありません。
処理負荷周りについてもう少し調べたいところです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2