콘텐츠로 이동

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를 제어하면 게임 상태에 반응하는 동적 이펙트(쉴드 강도, 캐릭터 속도, 원소 색상)를 유연하게 구현할 수 있습니다.