본문으로 건너뛰기

안동민 개발노트

본문 시작

동적 파라미터 갱신

블루프린트의 게임 상태를 사용자 변수에 지속적으로 전달해 캐릭터 속도에 따라 파티클 크기와 움직임이 반응하게 합니다.

이전 절에서 시스템 활성화와 기본 변수 제어를 익혔다면, 이제 실시간 반응 단계로 넘어갑니다.

이번 절에서는 게임 플레이 중 파라미터(Parameters)를 블루프린트에서 지속적이고 동적으로 업데이트하는 방법을 다룹니다.

체력에 따른 색 변화, 환경 속도에 따른 이동 변화, 목표 추적처럼 반응형 이펙트를 만들 때 반드시 필요한 기술입니다.

동적 파라미터 업데이트는 게임 상태나 입력값을 나이아가라 효과에 실시간으로 반영하는 방법입니다.

게임 값은 입력 계약을 거쳐 시뮬레이션 값이 된다

User Parameter는 Blueprint·C++처럼 Niagara 외부에서 시스템 인스턴스에 넣는 값이다.

  1. 게임 상태

    · READ 게임 상태 속도·체력·목표 위치를 원본에서 읽는다.

  2. 타입·범위 변환

    · MAP 타입·범위 변환 예: 속도 0..600을 강도 0..1로 clamp한다.

  3. 인스턴스 입력

    · SET 인스턴스 입력 User.PlayerSpeed Niagara Component에 이름·타입이 맞는 값을 설정한다.

  4. 모듈 소비

    · USE 모듈 소비 spawn rate·size·color 입력이 같은 값을 읽는다.

  5. 이벤트

    피격·재장전처럼 순간적으로 바뀌는 값

  6. 타이머

    온도·바람처럼 느리고 허용 오차가 큰 값

  7. Tick

    매 프레임 필요한 연속 값만, 동일 값이면 호출 생략


동적 파라미터 업데이트의 필요성

일회성으로 값을 설정하는 것을 넘어, 매 프레임마다 또는 특정 조건이 충족될 때마다 나이아가라 파라미터를 업데이트해야 하는 경우는 다음과 같습니다.

  • 실시간 데이터 반영: 플레이어의 속도, 체력, 총기 잔탄 수 등 게임 내 실시간으로 변하는 데이터를 파티클 효과에 반영하고 싶을 때.
  • 지속적인 추적: 파티클이 특정 액터(예: 플레이어, 적)의 위치나 움직임을 지속적으로 추적해야 할 때.
  • 환경 반응: 주변 환경(예: 바람의 방향과 세기, 지면의 색상)에 따라 파티클 효과가 변화해야 할 때.
  • 애니메이션 동기화: 캐릭터의 애니메이션 진행도에 맞춰 파티클 효과가 동기화되어야 할 때.

동적 파라미터 업데이트의 핵심

블루프린트에서 나이아가라 파라미터를 동적으로 업데이트하는 가장 일반적인 방법은 Event Tick 이벤트나 특정 업데이트 루프 내에서 Set Niagara Variable 노드를 사용하는 것입니다.

나이아가라 시스템 준비 (사용자 변수 노출)

블루프린트에서 동적으로 업데이트할 파라미터는 반드시 나이아가라 시스템 내에서 사용자 변수(User Parameter)로 노출되어 있어야 합니다.

나이아가라 시스템 에디터를 엽니다.

Parameters 패널에서 User 섹션을 찾습니다.

+ 버튼을 클릭하고 Add User Parameter에서 원하는 타입(예: Float, Vector, Color, Actor)을 선택하여 새 사용자 변수를 만듭니다. (예: User.TargetLocation, User.PlayerSpeed, User.CurrentHealth)

이 사용자 변수를 드래그하여 이미터나 파티클 모듈의 해당 입력 핀에 연결합니다.

  • 예시: 파티클의 이동 속도를 플레이어 속도에 맞춰 조절하고 싶다면, Add Velocity 모듈의 Velocity 입력에 User.PlayerSpeed 변수를 곱하는 노드를 연결합니다.
  • 예시: 파티클이 특정 대상의 위치를 따라가게 하고 싶다면, Attract Force 모듈의 Target Location 입력에 User.TargetLocation을 연결합니다.

Event Tick을 이용한 업데이트

나이아가라 시스템 컴포넌트가 추가된 블루프린트 (예: 캐릭터 블루프린트)를 엽니다.

Event Graph으로 이동합니다.

Event Tick 노드를 찾습니다. (Event Tick은 매 프레임마다 실행됩니다.)

Event Tick에서 실행 핀을 연결하여 다음 노드를 추가합니다.

  • Niagara Particle System 컴포넌트의 레퍼런스를 가져옵니다.
  • Set Niagara Variable 노드를 검색하여 추가합니다. (예: Set Niagara Variable Float, Set Niagara Variable Vector, Set Niagara Variable Object 등, 노출시킨 사용자 변수의 타입에 맞춰 선택).
  • Variable Name 입력에 나이아가라 시스템에서 노출시킨 사용자 변수의 정확한 이름을 입력합니다. (예: User.TargetLocation, User.PlayerSpeed)
  • In Value 입력에 동적으로 업데이트할 값을 연결합니다. 이 값은 블루프린트 내의 다른 변수, 함수 반환 값, 또는 다른 액터의 속성에서 가져올 수 있습니다.

실시간 업데이트는 비용이 누적되기 쉬우므로, 아래 체크처럼 읽기, 범위 변환, 변경 감지, 변수 전달, 모듈 소비 단계를 분리해 안정화합니다.

런타임 값은 읽기·변환·감지·전달·소비 경계를 지난다

원본 값을 매 프레임 그대로 보내지 말고, 화면에 의미 있는 범위와 변화량으로 줄인 뒤 User Parameter 계약을 통과시킨다.

  1. 게임 상태 읽기

    · READ 속도, 체력, 타겟 위치처럼 Blueprint가 소유한 원본을 가져온다. Get Velocity

  2. 효과 범위로 변환

    · MAP 게임 단위를 파티클 크기나 색에 맞는 좁은 범위로 바꾼다. Map Range Clamped

  3. 의미 있는 변화만 통과

    · GATE 이전 값과의 차이가 임계값보다 작으면 Set 호출을 건너뛴다. abs(Δ) ≥ ε

  4. User 값 전달

    · SET 정확한 이름과 타입의 Set Niagara Variable 노드를 한 번 호출한다. User.DustScale

  5. 모듈에서 소비

    · USE Spawn의 초기값인지 Update의 지속 변화인지 책임 위치를 고른다. Particle Update

  6. 화면이 즉시 따라야 할 때

    Tick 화면이 즉시 따라야 할 때 속도와 조준점처럼 프레임 반응이 필요한 값에만 쓴다.

  7. 상태가 드물게 바뀔 때

    Event 상태가 드물게 바뀔 때 피격, 스킬 발동, 장비 교체는 발생 시점에만 갱신한다.

  8. 외부 데이터를 계속 읽을 때

    DI 외부 데이터를 계속 읽을 때 액터·본·메시 표면은 Data Interface가 직접 공급한다.


직접 해보기: 속도에 따라 파티클 크기 조절하기

플레이어 캐릭터의 이동 속도에 비례하여 발밑에서 발생하는 먼지 파티클의 크기가 커지도록 만들어 보겠습니다.

나이아가라 시스템 준비

새로운 나이아가라 시스템 (New system from selected emitters > Fountain)을 생성하고 NS_SpeedDust라고 이름을 지정합니다.

Initialize Particle 모듈
  • Lifetime: 0.5 ~ 1.0 (Random Float)
  • Sprite Size: 5.0 (작은 기본 크기)
  • Color: 밝은 갈색 또는 회색
Add Velocity 모듈
  • Z축 Velocity20.0 정도로 낮게 설정하여 살짝 떠오르게 합니다.
  • X, Y축도 -10.0 ~ 10.0 정도로 작게 설정하여 미세하게 퍼지도록 합니다.

Add Gravity Force: 필요하다면 제거하거나 Gravity 값을 낮춰 연기가 천천히 퍼지도록 합니다.

Sprite Renderer
  • 적절한 연기 또는 먼지 텍스처를 가진 Translucent 머티리얼을 할당합니다. (예: M_Smoke_SubUV)
  • Soft Particle을 활성화합니다.
사용자 변수 노출
  • Parameters 패널User 섹션에서 + 버튼을 클릭하고 Add User Parameter > Float를 선택하여 User.PlayerSpeed라는 이름의 사용자 변수를 만듭니다. 기본값은 1.0으로 설정합니다.
파티클 크기 제어
  • Particle Update 섹션에 Scale Sprite Size 모듈을 추가합니다.
  • Scale FactorUniform 입력 핀에 다음 노드를 연결합니다.
    • Get Parameter 노드 (Parameter: User.PlayerSpeed)
    • Multiply (Float * Float) 노드 (두 번째 입력은 0.1이나 0.2와 같이 작은 값으로 설정하여 속도를 크기로 스케일링)
    • Multiply 노드의 결과를 Scale Sprite SizeUniform 입력에 연결합니다. 이렇게 하면 User.PlayerSpeed 값에 따라 파티클의 크기가 조절됩니다.

나이아가라 시스템을 저장합니다.

캐릭터 블루프린트 설정

언리얼 엔진의 기본 캐릭터 블루프린트 (BP_ThirdPersonCharacter 또는 여러분의 플레이어 캐릭터 블루프린트)를 엽니다.

Niagara Particle System 컴포넌트 추가
  • Components 패널에서 Niagara Particle System 컴포넌트를 추가하고, Niagara System 속성에 위에서 만든 NS_SpeedDust를 할당합니다.
  • 컴포넌트를 드래그하여 Mesh 컴포넌트의 자식으로 만들고, Parent Socketfoot_l 또는 foot_r과 같은 발 소켓을 할당합니다. LocationRotation 오프셋을 조절하여 발밑에 오도록 합니다.
Event Graph 로직 구현
  • Event Tick 노드에서 실행 핀을 연결하여 다음 노드를 추가합니다.
    • Get Velocity 노드 (캐릭터의 속도 벡터를 가져옴)
    • Vector Length 노드 (속도 벡터의 크기를 가져와 현재 속도를 Float로 얻음)
    • Map Range Clamped 노드 (속도 값을 원하는 범위로 매핑합니다)
      • In Range A: 0.0 (최소 속도)
      • In Range B: 600.0 (캐릭터의 최대 이동 속도, 프로젝트 설정에서 Max Walk Speed 확인)
      • Out Range A: 0.0 (파티클 크기의 최소 스케일)
      • Out Range B: 10.0 (파티클 크기의 최대 스케일, 나이아가라에서 설정한 Multiply 값과 연계)
    • Niagara Particle System 컴포넌트의 레퍼런스에서 Set Niagara Variable Float 노드를 추가합니다.
    • Variable NameUser.PlayerSpeed를 정확히 입력합니다.
    • In ValueMap Range Clamped 노드의 결과를 연결합니다.
  • 활성화/비활성화 로직: 캐릭터가 움직이지 않을 때는 파티클 시스템을 비활성화하는 로직을 추가하는 것이 좋습니다.
    • Vector Length 노드의 결과(Player Speed)가 5.0 (아주 작은 속도 임계값)보다 큰지 > 노드로 검사합니다.
    • 이 결과를 Branch 노드의 Condition에 연결합니다.
    • Branch 노드의 True 핀에서는 Niagara Particle System 컴포넌트의 Activate 노드를 연결합니다.
    • Branch 노드의 False 핀에서는 Niagara Particle System 컴포넌트의 Deactivate 노드를 연결합니다.

블루프린트를 컴파일하고 저장한 후, 게임을 플레이하여 캐릭터를 움직여 봅니다.

캐릭터가 빠르게 움직일수록 발밑 먼지 파티클의 크기가 커지는 것을 확인할 수 있을 겁니다.


값 기반 파라미터 해석

동적 파라미터를 빠르게 안정화하려면, 값과 화면 결과를 1:1로 묶어서 판단하는 것이 좋습니다.

  • User.PlayerSpeed = 0~100: 파티클 크기 변화가 거의 없고, 정지/걷기 상태에서 잔먼지만 보입니다.
  • User.PlayerSpeed = 200~400: 이동 방향 뒤쪽으로 먼지가 뚜렷해지며 발 위치 추적이 명확해집니다.
  • User.PlayerSpeed = 500~700: 먼지 볼륨이 급격히 커지므로 Scale Factor 상한을 두지 않으면 화면을 과도하게 가릴 수 있습니다.

튜닝 시에는 Map Range ClampedOut Range B를 먼저 조절하고, 그다음 Scale Sprite Size의 곱셈 계수(0.1, 0.2 등)를 미세 조정하는 순서가 안정적입니다.

일반적으로는 Out Range B8~10 범위에서 시작한 뒤, 곱셈 계수를 0.08~0.15 사이에서 보정하면 과한 증폭을 피하기 쉽습니다.

속도 구간을 먼저 읽고, 출력 상한부터 조절한다

원본 속도와 화면 크기를 1:1로 연결하면 전력 질주에서 먼지가 화면을 가린다. Clamp 상한을 정한 뒤 곱셈 계수로 감각만 보정한다.

  1. 0–100

    정지 · 걷기 크기 변화는 작고 발밑의 잔먼지만 남긴다.

  2. 200–400

    달리기 이동 방향 뒤쪽의 먼지 실루엣이 분명해진다.

  3. 500–700

    전력 질주 볼륨이 급증하므로 출력 상한에서 더 커지지 않게 한다.

  4. 원본 속도 읽기

    · INPUT Velocity 벡터의 길이를 구해 단일 Float로 만든다. Vector Length

  5. · INPUT
  6. 효과 범위 고정

    · CLAMP 0–700을 0–8 같은 제한된 DustScale 범위로 옮긴다. Map Range Clamped

  7. · CLAMP
  8. Sprite 크기에 적용

    · APPLY User 값을 Particle Update에서 읽어 살아있는 먼지에 반영한다. Scale Sprite Size

  9. · APPLY
  10. Out Range B · 8–10

    먼저 Out Range B · 8–10 최대 화면 점유율을 정해 과한 증폭을 막는다.

  11. 곱셈 계수 · 0.08–0.15

    다음 곱셈 계수 · 0.08–0.15 상한은 유지한 채 구간 사이의 체감만 미세 조정한다.


고급 동적 파라미터 업데이트 기법

  • Niagara Data Interface 활용: 특정 액터의 위치, 스켈레탈 메시의 본 정보, 이미지 샘플링 데이터 등을 나이아가라 시스템으로 직접 스트리밍하는 Niagara Data Interface를 활용하면 블루프린트의 Event Tick 루프를 거치지 않고도 동적으로 데이터를 업데이트할 수 있어 더욱 효율적입니다.
    • 예시: Niagara Data Interface Actor를 사용하여 파티클이 특정 타겟 액터를 따라가게 하거나, Niagara Data Interface Static Mesh를 사용하여 메시의 표면에서 파티클을 스폰하게 할 수 있습니다.
  • 이벤트 기반 업데이트: 모든 것을 Event Tick에서 처리하기보다는, 특정 이벤트(예: OnTakeDamage, OnHit)가 발생했을 때만 파티클 파라미터를 업데이트하도록 로직을 구성하여 성능을 최적화할 수 있습니다.
  • 비동기 업데이트: 매우 복잡한 계산이 필요하거나 많은 데이터를 전송해야 할 경우, Async Task 또는 Timer를 사용하여 매 프레임이 아닌 일정 시간 간격으로 데이터를 업데이트함으로써 메인 스레드의 부담을 줄일 수 있습니다.

업데이트 주기는 값의 변화 속도와 화면 민감도에 맞춰 고릅니다.

아래 표를 기준으로 Tick, Timer, Event, Data Interface 중 어떤 방식이 적합한지 결정합니다.

동적 값은 변화 속도에 맞춰 갱신한다

모든 값을 매 프레임 전달하면 반응성은 좋아지지만 비용과 노이즈가 커진다. 값의 성격에 맞춰 주기를 나눈다.

열 구성 · 방식 · 값 성격 · 권장 주기 · 방어선
방식값 성격권장 주기방어선
Tick 프레임 추적조준점, 카메라 거리, 빠른 이동처럼 지연이 바로 보이는 값.매 프레임, 단 변경 감지 후 필요한 값만 전달한다.상한과 보간을 두고 같은 값 반복 Set을 막는다.
Timer 간헐 갱신바람, 위험도, 환경 온도처럼 천천히 바뀌는 값.0.1초에서 0.5초 간격을 먼저 시험한다.간격을 늘려도 화면 차이가 작은지 비교한다.
Event 상태 변화피격, 발사, 장전, 스킬 시작처럼 원인이 명확한 값.변화가 생긴 순간 한 번 전달한다.초기값과 누락 이벤트를 별도로 검증한다.
Data Interface 직접 읽기Actor, Mesh, 본 위치처럼 나이아가라가 참조할 수 있는 데이터.블루프린트 반복 전달 대신 그래프에서 필요한 때 읽는다.Blueprint Set 루프와 중복되지 않게 소유자를 정한다.
Collection 공유 입력여러 이펙트가 같이 쓰는 시간, 날씨, 전역 강도 값.전역 값 변경 시 한 번 갱신한다.개별 시스템에서 다시 덮어쓰는 경로가 없는지 찾는다.

동적 파라미터는 값이 변하는 빈도와 보간 방식을 함께 설계해야 하므로, 업데이트 루프를 별도로 정리합니다.

동적 파라미터 업데이트 루프

Event Tick에서 Set Niagara Variable을 호출할 때는 변화량, 업데이트 빈도, 보간 여부를 함께 정해야 흔들림이 줄어듭니다.

  1. User 변수 노출

    Expose Niagara System에서 User.SpeedScale처럼 외부 입력값을 준비합니다.

  2. Blueprint 계산

    Compute 캐릭터 속도, 입력 강도, 거리 값을 게임 로직 쪽에서 먼저 정리합니다.

  3. 값 전달

    Set Set Niagara Variable Float, Vector, Linear Color 노드를 타입에 맞게 사용합니다.

  4. 보간

    Smooth 급격한 변화는 Blueprint 또는 Niagara 안에서 Interp로 완화합니다.

  5. 타입

    Float와 Vector를 잘못 보내면 값이 들어가지 않거나 기본값이 유지됩니다.

  6. 빈도

    매 Tick 전달이 필요한 값과 이벤트 때만 필요한 값을 분리합니다.

  7. 기본값

    값 전달 전에도 안전한 스폰율과 크기가 나오도록 기본값을 둡니다.

블루프린트 파라미터 업데이트 플로우 정리

Blueprint 값은 User Parameter 이름과 타입이 맞아야 Niagara로 들어간다

색, 위치, 강도 같은 런타임 값은 Blueprint 변수, User namespace, 모듈 입력이 같은 계약을 가져야 한다.

구간확인할 값통과 기준실패 신호
Blueprint 변수Float, Vector, Color, Bool 타입효과에서 필요한 값만 보냄타입 변환이 숨어 있음
Set Niagara VariableUser.ParamName 문자열이름과 namespace가 정확함철자 차이로 기본값 유지
Niagara User Param노출된 입력과 기본값그래프에서 같은 이름을 읽음연결 없는 기본값만 사용
Module Input속성에 적용하는 위치Particle 값으로 쓰임아래 모듈이 다시 덮어씀
Runtime Test극단값 테스트색, 크기, 강도가 즉시 변함PIE와 빌드 결과가 다름

실무에서는 다음 순서로 구조를 고정해두면 유지보수가 쉬워집니다.

  1. 개별 이펙트 값Set Niagara Variable로 직접 갱신합니다. (예: 단일 폭발 강도)
  2. 전역 공통 값8장 1절의 Niagara Parameter Collection으로 갱신합니다. (예: 전역 바람)
  3. 값 변경 트리거는 가능한 한 이벤트 기반(OnHit, OnAbilityActivated)으로 처리합니다.
  4. 서버 권위 값이 필요한 경우 서버에서 계산 후 클라이언트에 전파하고, 클라이언트는 렌더링 반영만 담당합니다.

동적 파라미터 업데이트는 나이아가라 시스템을 실시간 게임플레이와 연결하는 핵심 기술입니다.

Event Tick + Set Niagara Variable의 기본 패턴과 Niagara Data Interface 기반 고급 연동을 함께 익히면, 상황 반응형 이펙트를 안정적으로 구현할 수 있습니다.

이 흐름은 이후 고급 FX 설계의 공통 기반이 됩니다.

동적 파라미터 업데이트는 데이터 입력, 이미터 책임, 렌더 비용, 재현 기준으로 점검합니다.