콘텐츠로 이동

UE5 Niagara 파티클 시스템 C++ 제어

Niagara는 UE4에서 도입되어 UE5에서 주력으로 자리 잡은 차세대 파티클 시스템입니다. 이전 Cascade와 달리 GPU 시뮬레이션, 데이터 인터페이스, C++/Blueprint와의 유연한 연동을 지원합니다.

핵심 구성 요소:

  • Niagara System: 여러 Emitter를 포함하는 최상위 에셋
  • Niagara Emitter: 파티클 생성·업데이트 로직
  • User Parameters: 외부에서 값을 주입하는 변수 (C++/Blueprint로 제어)

MyGame.Build.cs
PublicDependencyModuleNames.AddRange(new string[]
{
"Niagara"
});

#include "NiagaraFunctionLibrary.h"
#include "NiagaraComponent.h"
#include "NiagaraSystem.h"
// 방법 1: 월드 위치에 일회성 이펙트 스폰 (자동 소멸)
void AWeapon::OnHit(const FHitResult& Hit)
{
if (!_hitEffect) return;
UNiagaraFunctionLibrary::SpawnSystemAtLocation(
GetWorld(),
_hitEffect, // UNiagaraSystem* 에셋
Hit.ImpactPoint, // 위치
Hit.ImpactNormal.Rotation(), // 회전
FVector(1.f), // 스케일
true, // 자동 소멸
true, // 풀 프리워밍
ENCPoolMethod::AutoRelease // 풀링
);
}
// 방법 2: 컴포넌트로 어태치 (지속 이펙트)
void ACharacter::AttachTrailEffect()
{
_trailComponent = UNiagaraFunctionLibrary::SpawnSystemAttached(
_trailEffect,
GetMesh(), // 부모 컴포넌트
FName("foot_l"), // 소켓 이름
FVector::ZeroVector,
FRotator::ZeroRotator,
EAttachLocation::SnapToTarget,
true
);
}

Niagara 에디터에서 User Parameters를 정의하면 C++에서 런타임에 값을 주입할 수 있습니다.

// Niagara 에디터에서 정의한 User Parameters:
// User.Color (LinearColor)
// User.Speed (float)
// User.Target (Vector3)
void AAbilityEffect::UpdateNiagaraParameters()
{
if (!_niagaraComponent) return;
// float 파라미터
_niagaraComponent->SetFloatParameter(
FName("User.Speed"), _currentSpeed);
// 벡터 파라미터
_niagaraComponent->SetVectorParameter(
FName("User.Target"), _targetLocation);
// 색상 파라미터
_niagaraComponent->SetColorParameter(
FName("User.Color"), FLinearColor(1.f, 0.2f, 0.f, 1.f));
// bool 파라미터
_niagaraComponent->SetBoolParameter(
FName("User.IsActive"), true);
// 텍스처 파라미터
_niagaraComponent->SetNiagaraVariableObject(
FName("User.CustomTexture"), _customTexture);
}

// Niagara에서 이벤트 발생 시 콜백 받기
#include "NiagaraDataInterfaceArrayFunctionLibrary.h"
UCLASS()
class AParticleEffect : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere)
UNiagaraComponent* _niagara;
void BeginPlay() override
{
Super::BeginPlay();
// 파티클 소멸 시 콜백
if (_niagara)
{
_niagara->OnSystemFinished.AddDynamic(
this, &AParticleEffect::OnNiagaraFinished);
}
}
UFUNCTION()
void OnNiagaraFinished(UNiagaraComponent* Component)
{
UE_LOG(LogTemp, Log, TEXT("Niagara effect finished"));
Destroy(); // 이펙트 완료 후 액터 제거
}
};

// 이펙트 On/Off
void AShield::SetShieldEffect(bool bActive)
{
if (!_shieldNiagara) return;
if (bActive)
{
_shieldNiagara->Activate(true); // true: 리셋 후 재생
}
else
{
// 방법 1: 즉시 중단
_shieldNiagara->Deactivate();
// 방법 2: 현재 파티클 자연 소멸 후 중단
_shieldNiagara->SetPaused(true);
// 방법 3: 새 파티클 생성 중단, 기존 파티클 소멸까지 대기
_shieldNiagara->DeactivateImmediate();
}
}
// 루프 이펙트 수명 제어
void AEnvEffect::ActivateForDuration(float Duration)
{
if (!_niagaraComponent) return;
_niagaraComponent->Activate(true);
FTimerHandle Timer;
GetWorldTimerManager().SetTimer(Timer, [this]
{
if (_niagaraComponent)
_niagaraComponent->Deactivate();
}, Duration, false);
}

Niagara Data Interface — 커스텀 데이터 전달

섹션 제목: “Niagara Data Interface — 커스텀 데이터 전달”

Niagara에서 C++ 데이터를 대량으로 전달할 때 Array Data Interface를 사용합니다.

#include "NiagaraDataInterfaceArrayFunctionLibrary.h"
// 적 위치 배열을 Niagara에 전달 (어트랙션/회피 이펙트)
void AEnemyRadar::UpdateNiagaraEnemyPositions()
{
if (!_radarEffect) return;
TArray<FVector> EnemyPositions;
for (AEnemy* Enemy : _visibleEnemies)
{
EnemyPositions.Add(Enemy->GetActorLocation());
}
// Niagara 에디터에서 Array<Vector3> 타입의 "User.EnemyPositions" 파라미터 필요
UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayVector(
_radarEffect,
FName("User.EnemyPositions"),
EnemyPositions
);
_radarEffect->SetIntParameter(
FName("User.EnemyCount"), EnemyPositions.Num());
}

// Blueprint에서 조작할 수 있도록 UPROPERTY 노출
UCLASS(BlueprintType)
class AFireEffect : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Effects")
UNiagaraComponent* FireNiagara;
// Blueprint에서 호출 가능한 파라미터 설정 함수
UFUNCTION(BlueprintCallable, Category = "Effects")
void SetFireIntensity(float Intensity)
{
if (FireNiagara)
{
FireNiagara->SetFloatParameter(FName("User.Intensity"),
FMath::Clamp(Intensity, 0.f, 1.f));
}
}
UFUNCTION(BlueprintCallable, Category = "Effects")
void SetFireColor(FLinearColor Color)
{
if (FireNiagara)
FireNiagara->SetColorParameter(FName("User.FireColor"), Color);
}
};

// NiagaraFunctionLibrary의 풀링 옵션 활용
void AProjectile::OnImpact(const FHitResult& Hit)
{
// AutoRelease: 완료 후 자동으로 풀에 반환
UNiagaraFunctionLibrary::SpawnSystemAtLocation(
GetWorld(),
_impactEffect,
Hit.ImpactPoint,
Hit.ImpactNormal.Rotation(),
FVector(1.f),
true,
true,
ENCPoolMethod::AutoRelease // 풀링 활성화
);
}

DefaultEngine.ini에서 풀 크기 설정:

[FXBudget]
MaxParticleSystems=100
NiagaraSystemPoolSize=20

API용도
SpawnSystemAtLocation월드 위치에 일회성 이펙트
SpawnSystemAttached컴포넌트에 어태치
SetFloatParameterfloat User Parameter 설정
SetVectorParameterVector3 파라미터 설정
SetColorParameterLinearColor 파라미터 설정
Activate(true)리셋 후 재생
Deactivate파티클 자연 소멸
ENCPoolMethod::AutoRelease오브젝트 풀링

C++에서 Niagara User Parameters를 제어하면 게임 상태에 반응하는 동적 이펙트(쉴드 강도, 캐릭터 속도, 원소 색상)를 유연하게 구현할 수 있습니다.


Niagara Parameter Collection — 전역 파라미터 공유

섹션 제목: “Niagara Parameter Collection — 전역 파라미터 공유”

UNiagaraParameterCollection은 여러 Niagara 시스템이 같은 값을 참조하도록 전역 파라미터를 공유합니다. 날씨·시간대 등 월드 상태를 모든 이펙트에 일괄 적용할 때 유용합니다.

#include "NiagaraParameterCollection.h"
#include "NiagaraParameterCollectionInstance.h"
UCLASS()
class AWeatherManager : public AActor
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "Niagara")
TObjectPtr<UNiagaraParameterCollection> WeatherNPC; // 에디터에서 할당
public:
void SetWindStrength(float Strength)
{
if (!WeatherNPC) return;
// 월드 인스턴스 접근 (월드별로 독립적인 값 유지)
UNiagaraParameterCollectionInstance* Instance =
GetWorld()->GetSubsystem<UNiagaraWorldSubsystem>()->GetParameterCollectionInstance(WeatherNPC);
// Collection에 정의된 파라미터 이름으로 값 설정
// 이 값을 참조하는 모든 Niagara 시스템에 즉시 반영됨
Instance->SetFloatParameter(FName("WindStrength"), FMath::Clamp(Strength, 0.f, 1.f));
}
void SetRainColor(FLinearColor Color)
{
if (!WeatherNPC) return;
auto* Instance = GetWorld()->GetSubsystem<UNiagaraWorldSubsystem>()
->GetParameterCollectionInstance(WeatherNPC);
Instance->SetVectorParameter(FName("RainColor"), FVector4f(Color));
}
};

NPC 사용 방법 요약:

  1. Content Browser → 우클릭 → FX → Niagara Parameter Collection 생성
  2. 컬렉션에 파라미터 추가 (WindStrength: float, RainColor: LinearColor)
  3. 각 Niagara 시스템의 모듈에서 해당 컬렉션 파라미터를 바인딩
  4. C++에서 GetParameterCollectionInstance()SetFloatParameter() 호출

fx.Niagara.Debug.ShowStats 1 — Niagara 통계 오버레이
fx.Niagara.Debug.Visualize 1 — 파티클 시각화
fx.Niagara.MaxGPUParticlesSpawnPerFrame 100 — GPU 파티클 생성 상한
stat Niagara — CPU/GPU 파티클 비용 프로파일링