본문 바로가기

캐릭터와 무기 관련 간단한 이펙트

애니메이션과 소켓에 차징·피격·무기 궤적·총구 화염·탄피 효과를 연결해 캐릭터 액션의 시각 피드백을 구현합니다.

캐릭터와 무기는 플레이어가 게임 내내 가장 자주 보는 대상입니다. 그래서 스킬을 모을 때의 빛, 맞았을 때의 스파크, 칼을 휘두를 때의 궤적, 총을 쏠 때의 화염과 튀어 나가는 탄피 같은 효과가 행동에 대한 즉각적인 반응 역할을 합니다. 이런 효과도 발자국이나 마법처럼 블루프린트와 애니메이션 시스템에 연결해 설계해야 합니다. 이 글에서는 캐릭터에 붙는 차징과 피격 효과, 무기에 붙는 휘두르기 궤적과 총구 화염, 탄피 효과의 설정을 살펴보고, 차징 진행률을 넘기는 계산과 효과마다 켜고 끄는 기준을 정리합니다.


캐릭터에 붙는 효과

캐릭터의 효과는 주로 캐릭터의 움직임이나 상태가 바뀔 때, 그리고 특정 스킬을 쓸 때 생깁니다. 아래의 두 효과는 시간의 모양이 반대입니다. 스킬 차징은 버튼을 누르고 있는 동안 계속 이어지며 게임이 넘기는 진행률에 따라 세지고, 피격은 맞은 순간 한 번 터지고 곧바로 사라집니다. 그래서 차징은 Spawn Rate와 사용자 파라미터로, 피격은 Spawn Burst Instantaneous와 맞은 위치 정보로 만듭니다.

스킬 차징

차징(charging)은 스킬을 쓰려고 힘을 모으거나 기다릴 때 나타나는 효과입니다. NS_SkillCharge를 만든다면 Spawn Rate는 낮게 시작해 차징 시간에 따라 점점 늘리고, Lifetime은 0.5초에서 1.0초 사이로 비교적 짧게 둡니다. 스프라이트 크기는 작게 시작해 커지게 하고, 색은 스킬의 속성에 맞춰 불 스킬이라면 주황, 전기 스킬이라면 파랑으로 정합니다. 초기 위치는 캐릭터 주변에 구나 원기둥 모양으로 퍼뜨리거나 손, 발 같은 소켓에 붙이고, 초기 속도는 캐릭터 쪽으로 모이거나 돌면서 위로 솟아오르게 줍니다.

움직임에서는 Point Attraction Force로 입자를 캐릭터의 중심 쪽으로 끌어당깁니다. 이때 캐릭터의 중심과 입자의 위치가 같은 좌표 공간인지 확인해야 하며, 아무 음수 벡터나 주면 늘 중심을 향하는 것은 아닙니다. Curl Noise Force 같은 노이즈 힘을 더하면 에너지가 휘몰아치거나 불규칙하게 떨리는 느낌이 납니다. 시간에 따른 변화로는 Scale Color로 색이 점점 밝아지거나 마지막에 강하게 빛나게 하고, Scale Sprite Size로 입자가 생겨 커졌다가 캐릭터에게 빨려 드는 느낌을 줍니다. 렌더링은 빛나는 에너지나 스파크 텍스처를 쓰는 Additive나 Translucent의 Unlit 머티리얼로 합니다.

블루프린트에서는 캐릭터의 차징 상태에 따라 나이아가라 컴포넌트의 User.ChargeAmount처럼 실제로 만든 사용자 파라미터를 갱신합니다. 나이아가라 쪽의 Spawn Rate나 색, 크기 모듈이 그 값을 읽도록 연결되어 있어야 합니다. 차징이 끝나거나 취소되면 Deactivate를 부르고, 기존 입자가 수명을 마치게 할지 곧바로 없앨지를 수명 주기 정책으로 정합니다. 취소되거나 Actor가 끝나는 경로에서도 같은 정리를 합니다.

피격

피격(hit) 효과는 캐릭터가 공격받았을 때 터지는 짧고 강한 효과입니다. NS_CharacterHit를 만든다면 한 번에 만들어야 하므로 Spawn Burst Instantaneous가 꼭 필요하고, Spawn Count는 피격의 세기에 따라 정합니다. Lifetime은 0.1초에서 0.3초 사이로 아주 짧게, 스프라이트 크기는 작게 시작해 빠르게 커지게 하며, 색은 피격의 속성에 따라 물리 공격이라면 붉은 스파크, 독이라면 녹색, 마법이라면 보라색으로 정합니다.

움직임에서는 Add Velocity로 공격 방향의 반대쪽이나 사방으로 세게 퍼지게 하고, Gravity Force와 Drag로 파편이 빨리 떨어지고 사라지게 합니다. 시간에 따른 변화로는 Scale Color로 순간 밝게 터졌다가 어둡고 투명하게 사라지게 하고, Scale Sprite Size로 빠르게 커졌다가 줄어드는 충격파 느낌을 줍니다. 렌더링은 스파크나 파편, 피, 연기 텍스처를 쓰는 Additive나 Translucent의 Unlit 머티리얼로 합니다.

블루프린트에서는 Point Damage의 Hit Location과 Hit Normal, 또는 유효한 Hit Result를 넘겨받는 게임플레이 이벤트에서 Spawn System at Location을 부릅니다. Event AnyDamage 자체는 Hit Result를 주지 않으므로 이 용도에 맞지 않습니다. Location에는 Hit Result의 Impact Point를 넣고, Rotation은 Make Rot From Z로 Impact Normal을 회전으로 바꿔 넣습니다. 이렇게 로컬 +Z로 뿜어 낸다면 따로 월드의 법선을 같은 회전에 한 번 더 적용하지 않습니다. 그리고 Auto Activate를 끄고 만든 컴포넌트에 Set Niagara Variable로 선언해 둔 사용자 값을 넣은 뒤 Activate합니다. DamageType 클래스를 그대로 Float에 넣지 말고, 효과의 색이나 정수 분류처럼 실제 나이아가라 입력으로 바꿔 넘깁니다.


차징 진행률과 입자의 나이

차징 진행률을 넘기는 계산을 따라가 봅니다. 연습을 위해 차징 시간을 1.5초로 정하고, 켜져 있는 동안 ChargeAmount = Clamp(흐른 시간 ÷ 1.5, 0, 1)을 넘긴다고 합시다. 나이아가라의 Spawn Rate를 20 + 40 × ChargeAmount(초당 입자 수)에 연결하면, 0.75초의 진행률은 0.75 ÷ 1.5 = 0.5이고 생성률은 20 + 40 × 0.5 = 40개/초입니다.

흐른 시간ChargeAmountSpawn Rate
0초020개/초
0.75초0.540개/초
1.5초 이상160개/초

사용자 파라미터를 만들고 값을 보내기만 하면 이 식이 저절로 붙는 것은 아니므로, 모듈의 입력에 실제로 연결해야 합니다. 또 차징 진행률은 게임이 정하는 공통의 시계이고, 입자마다의 NormalizedAge와는 다른 값입니다.


무기에 붙는 효과

무기의 효과는 공격과 피격, 발사처럼 무기의 기능과 바로 이어져 있습니다. 그래서 캐릭터의 몸이 아니라 무기의 소켓이 효과의 위치를 정하고, 효과를 켜는 시점도 애니메이션 노티파이나 발사 로직처럼 무기가 실제로 동작하는 순간에 맞춥니다. 아래에서는 휘두르는 동안 이어지는 궤적과, 쏘는 순간 한 번 생기는 총구 화염과 탄피를 나눠 봅니다.

휘두르기 궤적

검이나 도끼 같은 근접 무기를 휘두를 때 남는 잔상이나 에너지의 궤적입니다. NS_WeaponSwing을 만든다면 Spawn Rate는 20에서 50 사이의 보통 정도로, Lifetime은 0.2초에서 0.5초 사이로 짧게, 스프라이트 크기는 작게 시작해 커지게 두고, 색은 무기나 스킬의 속성에 맞춰 불검은 주황, 얼음검은 파랑, 일반 검은 흰색이나 회색으로 정합니다. 움직임은 Add Velocity로 무기가 움직이는 방향이나 도는 방향으로 주고, 노이즈 힘을 약하게 더해 흔들리는 느낌을 줍니다. 시간에 따라서는 Scale Color로 투명하게 사라지게 하고, Scale Sprite Size로 퍼지며 커지게 합니다.

렌더링에는 에너지나 스파크, 바람을 가르는 텍스처를 쓰는 Sprite Renderer와, 궤적을 잇는 Ribbon Renderer를 씁니다. 리본으로 지나간 자리를 이으려면, 소켓에 붙은 나이아가라 컴포넌트가 월드 공간의 입자를 계속 만들어 이전 위치들을 남겨야 합니다. Ribbon ID와 연결 순서, 너비를 맞추며, 렌더러만 더하거나 모든 입자를 Local Space로 두면 지나간 월드의 궤적과 달라집니다. 머티리얼은 Additive나 Translucent의 Unlit을 씁니다.

블루프린트에서는 애니메이션 몽타주(Anim Montage)의 휘두르는 구간에 애니메이션 노티파이(Anim Notify)를 더하고, 그 노티파이에서 나이아가라 컴포넌트를 Activate해 효과를 켠 뒤 휘두르기가 끝날 때 Deactivate합니다. 시작과 끝이 있는 Notify State 구간을 쓰고, 몽타주가 중단되거나 무기를 바꾸거나 스킬이 취소될 때도 정리하며, 정상적으로 끝나는 노티파이만 기다리지 않습니다. 파티클 시스템은 Spawn System Attached로 무기의 소켓에 붙입니다.

총구 화염과 탄피

총을 쏠 때 총구에서 뿜어 나오는 화염(muzzle flash)과 튀어 나가는 탄피입니다. 총구 화염 NS_MuzzleFlash는 Spawn Burst Instantaneous로 적은 수를 한 번에 만들고, Lifetime은 0.05초에서 0.1초 사이로 아주 짧게, 스프라이트 크기는 작게 시작해 빠르게 커지게, 색은 밝은 주황과 노랑, 빨강으로 둡니다. Add Velocity로 총구 앞쪽으로 세게 뿜고 작은 노이즈를 더하며, Scale Color로 순간 가장 밝았다가 곧바로 투명해지게, Scale Sprite Size로 빠르게 커졌다가 사라지게 합니다. 렌더링은 주로 SubUV를 쓰는 총구 화염 텍스처의 Additive, Unlit 머티리얼로 하고, 짧은 순간 총구 주변을 밝히려면 Light Renderer를 쓰되 비용에 주의합니다.

탄피 NS_ShellEject는 Spawn Burst Instantaneous로 1개를 만들고 Lifetime을 0.5초에서 1.0초 사이로 둡니다. Mesh Renderer를 쓰고 메시 크기를 실제 탄피 크기에 맞게 작게 정하며, 초기 속도는 배출구에서 옆이나 뒤로 튕겨 나가게 줍니다. 움직임에서는 Gravity Force를 강하게 주어 땅으로 떨어지게 하고 Drag는 적당히 줍니다. 표면에 반응해야 한다면 Collision을 더해 반발과 마찰을 조절하되, 입자의 충돌이 탄피가 굴러가는 강체 운동까지 정확히 보장하지는 않습니다. Collision 바로 뒤에는 Solve Forces and Velocity를 둡니다. 회전은 Particle Spawn에서 초기 메시 방향을 정하고 Particle Update의 Update Mesh Orientation 같은 실제 회전 모듈로 줍니다. 변수를 선언하기만 해서는 회전이 생기지 않습니다. 렌더링은 Mesh Renderer에 탄피 메시를 지정하고 Default Lit 셰이딩 모델을 씁니다.

블루프린트에서는 총기 블루프린트나 캐릭터의 발사 로직에서 총구 화염에는 Spawn System Attached를, 탄피에는 Spawn System at Location을 씁니다. 총구 화염은 총구 소켓에 붙이고, 실제로 발사되는 순간에 정확히 만들어지게 합니다.


효과마다 켜고 끄는 기준

효과마다 무엇으로 시작하고, 어느 공간을 기준으로 하며, 언제 끝나는지를 표로 정리하면 다음과 같습니다.

효과시작하는 입력공간의 기준끝나는 조건
차징게임플레이 상태의 시작손이나 무기의 소켓완료와 취소 모두 Deactivate
무기 궤적Notify State의 시작월드 공간의 잔상구간 종료나 몽타주 중단
피격판정이 넘겨준 표면 정보Impact Point와 Normal한 번의 버스트 완료
총구 화염실제 발사 이벤트총구 소켓짧은 Once 재생
탄피실제 발사 이벤트배출 소켓에서 월드로Lifetime 종료

연결할 때 몇 가지를 더 챙깁니다. 캐릭터와 무기의 효과는 애니메이션과 타이밍이 정확히 맞아야 하므로, 애니메이션 시퀀스나 몽타주에 노티파이를 더해 시스템을 켜고 끄거나 Spawn 노드를 부릅니다. 캐릭터의 속도나 체력, 무기의 정보는 분명히 연결한 사용자 파라미터나 지원되는 Actor Component 데이터 인터페이스, 직접 만든 데이터 인터페이스로 넘겨 효과를 조절합니다. 공격이 빗나갔을 때나 체력이 낮을 때처럼 특정 조건에서만 효과가 생겨야 한다면 블루프린트의 Branch로 만드는 로직을 제어합니다.

총구 화염이나 피격처럼 짧은 시간에 아주 자주 생기는 효과는 Spawn 노드의 내장 Pooling Method나 직접 만든 풀링으로 비용을 줄입니다. 캐릭터와 무기는 게임 월드의 스케일에 직접 영향을 받으므로, 입자의 크기와 속도도 월드 스케일에 맞춰 조절합니다.

발사와 피격의 게임 판정은 화면에 보이는 이벤트와 구분하고, 반복 공격과 취소를 함께 확인합니다. 소켓이 사라지거나 무기를 바꿀 때 컴포넌트가 남지 않아야 하며, 풀에서 회수된 컴포넌트의 참조를 다시 다루지 않습니다.


정리

  • 차징 효과는 사용자 파라미터로 진행률을 받아 생성률과 색, 크기에 연결하며, 완료와 취소, Actor 종료에서 모두 정리합니다.
  • 피격 효과는 Hit 정보를 넘겨받는 이벤트에서 Impact Point와 Make Rot From Z(Impact Normal)로 만들고, 값을 넣은 뒤 Activate합니다.
  • 무기 궤적은 소켓에 붙은 컴포넌트가 월드 공간의 입자를 계속 남겨 리본으로 잇고, Notify State 구간과 중단 경로에서 켜고 끕니다.
  • 총구 화염은 아주 짧은 Once 재생으로, 탄피는 메시 입자와 중력, 실제 회전 모듈로 만듭니다.
  • 차징 진행률은 게임의 공통 시계이고 입자의 NormalizedAge와 다르며, 게임 판정과 화면의 효과는 따로 다룹니다.

연습 문제

1. 0.30초의 차징과 취소

본문의 차징 예에서 0.30초의 진행률과 생성률은 얼마일까요? 그런데 0.25초에 스킬이 취소되었고, 켜져 있는 동안에만 값을 갱신하는 정책이라면, 0.30초에 계산한 값을 다시 넘겨 효과를 켜야 할까요? 차징 진행률이 0.5일 때 모든 입자의 NormalizedAge도 0.5일까요?

해설 보기

계산하면 진행률은 0.30 ÷ 1.5 = 0.2이고, 생성률은 20 + 40 × 0.2 = 28개/초입니다.

그러나 이미 취소된 상태라면 켜져 있을 때의 갱신이나 다시 켜는 일을 하지 않고, 취소의 정리 정책을 적용합니다. 또 차징 진행률은 게임의 공통 시계이고, NormalizedAge는 입자마다의 나이를 수명으로 나눈 값입니다. 서로 다른 시점에 생긴 입자들은 같은 ChargeAmount를 읽어도 나이가 서로 다르므로, 모두 0.5가 되지는 않습니다. 남은 입자를 마무리할지 곧바로 없앨지는 처음 정한 수명 정책에 따릅니다.

2. 끝나지 않는 칼날 궤적

공격 몽타주가 중간에 끊기면 무기 궤적 효과가 꺼지지 않고 칼에 계속 남아 있습니다. 무엇을 고쳐야 할까요?

해설 보기

효과를 끄는 일을 정상적으로 끝나는 노티파이에만 맡겼기 때문에, 몽타주가 중간에 끊기면 그 노티파이가 오지 않아 효과가 계속 켜져 있는 것입니다.

시작과 끝이 있는 Notify State 구간을 쓰고, 몽타주가 중단되거나 블렌드 아웃될 때, 무기를 바꿀 때, 스킬이 취소될 때에도 Deactivate를 부르도록 정리 경로를 더합니다.

3. 휘둘러도 생기지 않는 궤적

칼에 붙인 효과에 Ribbon Renderer를 더했는데, 칼을 휘둘러도 궤적이 칼 모양 그대로 따라다닐 뿐 지나간 자리에 남지 않습니다. 이미터는 Local Space입니다. 왜 그럴까요?

해설 보기

Local Space의 입자는 부모인 칼을 따라 함께 움직이므로, 이전에 만든 입자도 칼과 같이 옮겨 가서 지나간 자리에 남지 않습니다. 그래서 리본이 칼 모양 그대로 따라다닙니다.

이미터의 Local Space를 꺼서 입자가 생긴 월드 위치에 남게 하고, 휘두르는 동안 소켓에서 입자를 계속 만들어 같은 Ribbon ID와 순서로 잇습니다. 그러면 칼이 지나간 자리를 따라 궤적이 남습니다.

다음 글 파티클 효과의 기본 최적화 기법에서는 지금까지 만든 효과를 대상 플랫폼의 예산에 맞추는 방법을 비용의 종류별로 정리합니다.