icon안동민 개발노트

나이아가라 스크립트 기본 개념


 나이아가라 스크립트는 언리얼 엔진의 나이아가라 파티클 시스템에서 사용되는 특화된 스크립팅 언어입니다.

 이 스크립트를 통해 개발자는 복잡한 파티클 동작을 정밀하게 제어하고, 고급 시각 효과를 구현할 수 있습니다.

나이아가라 스크립트의 개념과 목적

  1. 개념 : HLSL (High-Level Shader Language) 기반의 특수 목적 언어
  2. 목적
  • 파티클 동작의 정밀한 제어
  • 복잡한 시각 효과 구현
  • 성능 최적화된 파티클 로직 작성

일반 프로그래밍 언어와의 차이점

  1. 실행 환경 : GPU에서 병렬 처리를 위해 최적화됨
  2. 문법 : HLSL과 유사하지만, 파티클 시스템에 특화된 기능 포함
  3. 범위 : 파티클 속성 조작에 중점을 둠
  4. 성능 : 대량의 파티클을 효율적으로 처리하도록 설계됨

스크립트 에디터 인터페이스

  1. 코드 편집 영역 : 스크립트 작성 공간
  2. 파라미터 패널 : 스크립트에서 사용할 변수 및 파라미터 정의
  3. 컴파일 버튼 : 스크립트 컴파일 및 오류 확인
  4. 디버그 창 : 컴파일 오류 및 경고 메시지 표시

기본적인 스크립트 작성 방법

  1. 새 스크립트 모듈 추가
  2. 입력 및 출력 파라미터 정의
  3. 스크립트 로직 작성
  4. 컴파일 및 테스트

 예제 : 간단한 파티클 이동 스크립트

void MoveParticle(inout float3 Position, float3 Velocity, float DeltaTime)
{
    Position += Velocity * DeltaTime;
}

스크립트 실행 순서

  1. 초기화 (Spawn) : 파티클 생성 시 실행
  2. 업데이트 (Update) : 매 프레임 실행
  3. 이벤트 (Event) : 특정 조건 충족 시 실행

 예제 : 실행 순서를 고려한 스크립트

void InitializeParticle(inout float3 Position, inout float3 Velocity)
{
    Position = float3(0, 0, 0);
    Velocity = float3(rand() - 0.5, rand() - 0.5, rand()) * 100.0;
}
 
void UpdateParticle(inout float3 Position, inout float3 Velocity, float DeltaTime)
{
    Position += Velocity * DeltaTime;
    Velocity.z -= 9.8 * DeltaTime; // 중력 적용
}
 
void OnCollision(inout float3 Velocity)
{
    Velocity = reflect(Velocity, float3(0, 0, 1)); // 지면 반사
}

변수 선언과 사용

  1. 입력 변수 : in 키워드 사용
  2. 출력 변수 : out 키워드 사용
  3. 입출력 변수 : inout 키워드 사용

 예제

void UpdateParticleColor(in float Age, 
                         in float Lifetime, 
                         out float4 Color)
{
    float NormalizedAge = Age / Lifetime;
    Color = lerp(float4(1, 0, 0, 1), float4(0, 0, 1, 0), NormalizedAge);
}

내장 함수 활용

 나이아가라는 다양한 내장 함수를 제공합니다.

  1. 수학 함수 : sin, cos, lerp 등
  2. 벡터 연산 : dot, cross, normalize 등
  3. 랜덤 함수 : rand, rand2, rand3 등

 예제 : 내장 함수를 사용한 복잡한 동작

void CreateSpiralMotion(inout float3 Position, float Time, float Frequency, float Radius)
{
    float Angle = Time * Frequency;
    Position.x = cos(Angle) * Radius;
    Position.y = sin(Angle) * Radius;
    Position.z += Time * 10.0;
}

스크립트 디버깅 기법

  1. 프린트 디버깅 : PrintDebug 함수 사용
PrintDebug(Position);
  1. 시각적 디버깅 : 파티클 속성을 색상이나 크기로 표현
Color = float4(NormalizedValue, 0, 0, 1); // 빨간색으로 값 표현
  1.  단계별 실행 : 나이아가라 디버거 사용 (가능한 경우)

  2.  조건부 실행 : 특정 조건에서만 코드 실행

if (ParticleID == 0) // 첫 번째 파티클만 디버그
{
    PrintDebug(Velocity);
}

효율적인 스크립트 작성을 위한 팁

  1. 최적화 고려
  • 불필요한 연산 최소화
  • 조건문 사용 줄이기
  • 루프 사용 시 주의 (가능한 한 병렬 처리에 적합하게 설계)
  1. 재사용성
  • 공통 로직을 함수로 분리
  • 파라미터화를 통한 유연성 확보
  1. 가독성
  • 명확한 변수 및 함수 이름 사용
  • 주석을 통한 코드 설명
  1. 모듈화
  • 기능별로 스크립트 분리
  • 복잡한 로직을 작은 단위로 나누기

실제 적용 예시 : 불꽃 효과 스크립트

void InitializeFireParticle(out float3 Position, 
                            out float3 Velocity, 
                            out float Lifetime, 
                            in float3 EmitterLocation)
{
    // 초기 위치 설정
    float Radius = rand() * 10.0;
    float Angle = rand() * 2.0 * PI;
    Position = EmitterLocation + float3(cos(Angle) * Radius, sin(Angle) * Radius, 0);
 
    // 초기 속도 설정
    Velocity = float3(rand() - 0.5, rand() - 0.5, rand() + 1.0) * 50.0;
 
    // 수명 설정
    Lifetime = rand() * 2.0 + 1.0; // 1 to 3 seconds
}
 
void UpdateFireParticle(inout float3 Position, 
                        inout float3 Velocity, 
                        inout float4 Color, 
                        in float Age, 
                        in float Lifetime, 
                        float DeltaTime)
{
    // 위치 업데이트
    Position += Velocity * DeltaTime;
 
    // 속도 업데이트 (상승 및 흔들림 효과)
    Velocity.z += 20.0 * DeltaTime;
    Velocity.xy += (rand2() - 0.5) * 10.0 * DeltaTime;
 
    // 색상 변화
    float NormalizedAge = Age / Lifetime;
    Color = lerp(float4(1, 0.5, 0, 1), float4(0.5, 0, 0, 0), NormalizedAge);
 
    // 크기 변화
    float Size = lerp(10.0, 1.0, NormalizedAge);
    
    PrintDebug(Size); // 크기 변화 디버깅
}

 이 예시 스크립트는 불꽃 효과를 위한 파티클의 초기화와 업데이트 로직을 구현합니다. 파티클의 위치, 속도, 색상, 크기가 시간에 따라 변화하며, 자연스러운 불꽃 움직임을 시뮬레이션합니다.

 나이아가라 스크립트는 강력하면서도 특화된 도구입니다. 이를 효과적으로 활용하면 복잡하고 아름다운 파티클 효과를 구현할 수 있습니다. 스크립트 작성 시 성능과 가독성의 균형을 유지하고, 지속적인 실험과 최적화를 통해 더욱 효율적이고 인상적인 시각 효과를 만들어 나가세요.