무엇이 타격감을 만드는가
소울라이크 게임에서 가장 중요한 타격감을 어떻게 구현하는가.
오늘도 아침 일찍 일어나서, 운동 가기 전인 저녁 다섯 시 반까지 약 열한 시간 정도를 게임 개발에 썼다. 요즘 이걸 하느라 주주에 하루 평점이 1~2점대로 머물고 있다…ㅋㅋ
내가 지금 게임 개발을 제대로 하고 있다고는 얘기를 못하겠다.
사실 기간이 조금 촉박해서 AI를 최대한 활용해 지름길이란 지름길은 다 가고 있는데, 그럼에도 이 게임 개발이야말로 종합 예술의 결정체라는 생각이 문득 든다.
나는 이 게임 하나를 만들기 위해 작가가 되었다가, 애니메이터가 되었다가, 개발자가 되었다가, 또 쥐뿔도 모르는 음악가도 되어야 한다.
AI 시대라는 게 이럴 때 보면 참 좋은 거 같기는… 한 거 같다.
아무튼! 오늘도 블로그 쓰기 미션엔 연차가 없다. 뭐라도 써야 하는데 오늘 한 거라곤 게임 개발밖에 없어서, 그거에 대해서 좀 써보려고 한다.
한 이틀 전부터 전투씬을 작업하고 있는데, 3D 캐릭터나 애니메이션은 AI로 그럭저럭 뽑는다 쳐도, 막상 테스트를 좀 해보니 이게 맛이 없다.
분명 때리기도 하고 맞기도 하는데 밋밋하고, 그 게임의 “질감” 이라는 게 전혀 없는 것 같았다.
뭐가 문제일까 고민을 좀 하다가… 어차피 지금 내가 만드는 게 소울라이크니까 겸사겸사, 어제 저녁에 친구들이랑 엘든링을 좀 했다.
분명히 엘든링에는 내가 만드는 게임엔 없는 게 있다. 타격감. 몹을 때릴 때 내 화면도 살짝 흔들리고, 몹도 그에 맞춰 반응하고, 무기에 따라 나는 소리도 다르고.. 맞았을 때는 진짜 맞는 것 같은.. 그런 맛있는 타격감이 흔히 말하는 “잘 만든 게임” 엔 존재한다.
그럼 이걸 어떻게 해야 구현할 수 있을까?
오늘은 그걸 좀 고민해봤다.
애니메이션? ㄴㄴ 그건 문제가 아님.
처음엔 애니메이션이 부족해서 그런 줄 알았다.
그래서 Meshy 프롬프트 손보고, Mixamo 애니도 다시 골라 붙여봤는데… 뭘 해도 그대로 밋밋. 아 이거 애니로 해결될 문제가 아니구나 싶어서 좀 찾아봤다.
결론은
타격감은 애니메이션이 만드는 게 아니다.
임팩트 순간에 짧게 정지하고, 화면이 흔들리고, 몹이 번쩍하고, 소리가 겹치고… 이런 밀리초짜리 연출들이 다 겹쳐서 뇌가 “때렸다” 고 인식하는 것.
애니는 그저 겉껍데기고 진짜 “맛” 은 다른 곳에서 나온다.
임팩트 순간에 잠깐 멈춰! - 히트 스톱
검이 몹에 닿는 그 순간, 피격을 하는 객체와 맞는 객체 모두 아주 짧게 정지한다.
라이트 히트는 50100ms, 헤비 히트는 100200ms 정도.
원래 격투 게임에서 시작된 기법인데 소울라이크가 그대로 흡수한 것 같다.
난 이게 없었다.
그래서 검이 그냥 몹을 통과하듯이 스쳐 지나갔던 것.
붙여봤더니 진짜 다르다. 겨우 몇 프레임 정지하는 것뿐인데 검이 몹에 “박히는” 느낌이 확 생긴다.
화면 흔들고, 번쩍번쩍 — 셰이크 + 플래시
카메라를 200300ms 짧게 흔들고, 맞은 몹을 6080ms 흰색으로 번쩍이게 한다.
이 둘은 각자로는 별거 아닌데, 위의 히트 스톱이랑 같이 트리거되면 그때부턴 뇌가 진짜로 “때렸다” 고 반응한다더라. 실제로 붙여보니까 진짜 그랬다.
이거 안 넣으면 원거리 무기 쓸 때 특히 답이 없다. 활 쐈는데 맞았는지 안 맞았는지 알 수가 없다.
세 개 (히트 스톱 + 셰이크 + 플래시) 를 한 함수로 묶어놓고 히트 판정 순간에 한 줄로 호출하도록 짜뒀다.
앞으로 계속 재사용할 거니까.
소리는 Three layers로 쌓는다
“탁” 소리 한 방으로는 얕다.
액션 영화 사운드 디자이너들이 쓰는 3층 레시피가 있다는 걸 알게 됐다.
- 위층 (“쨍”) — 0~30ms, 고주파. 금속 링, 나무 부러지는 순간의 날카로운 소리.
- 중층 (“쿵”) — 30~100ms, 저주파. 무게감·타격체의 체감.
- 하층 (여운) — 100~300ms, 넓은 대역. 비명·바람·잔향.
이 세 개를 겹쳐서 동시에 재생.
그리고 매번 pitch 를 ±10% 랜덤화. 안 하면 스무 번쯤 때리다가 귀가 지쳐서 게임 끈다.
헤비 히트는 여기서 조금 더 뽑을 수 있다. 중층 소리의 pitch 를 20% 정도 낮추고 sub-bass 하나 얹으면 확실히 무거워지더라.
몹의 공격은 네 조각으로 쪼갠다
이게 소울라이크가 재밌는 이유인 것 같다.
지금까지 나는 몹이 공격하면 그냥 “공격 애니 재생하고 hitbox 켜기” 정도로 처리했었다. 그러니까 몹이 로봇처럼 쉬지 않고 때린다. 대응 창이 없다. 어우 짜증나.
소울라이크는 몹의 공격 하나를 이렇게 네 단계로 쪼갠다.
- 전조 (200~400ms) — “나 지금 뭐 할 거야” 를 몸으로 알리는 구간. 플레이어가 이걸 보고 반응 준비.
- 준비 (100~200ms) — 커밋됨. 이 시점부턴 취소 불가.
- 타격 (50~150ms) — 여기서만 hitbox 가 켜진다.
- 회복 (300~600ms) — 몹이 무방비. 이게 카운터 창.
여기서 중요한 건 회복 구간을 길게 잡는 거였다. 회복이 짧으면 결국 아까 얘기한 그 로봇 몹이 되는 거고, 회복이 넉넉해야 플레이어가 “지금이다!” 하고 되받아치는 창이 생긴다.
그 창이 있어야 소울라이크 특유의 그 리듬이 살아난다.
여기서 진짜 유명한 안티패턴 하나
전조 단계에서 취소 조건 안 걸어놓으면 난이도가 너무 쉬워진다.
플레이어가 전조 보자마자 대시로 쏙 빠져나갔는데, 몹이 그대로 공격을 완주한다. 허공을 후려친다.
그래서 전조 단계엔 매 tick 사거리 재확인 → 벗어났으면 즉시 취소하고 추격 상태로 복귀.
몹의 완성도를 조금 높여준다.
회피에는 무적 프레임을 심는다
i-frame.
회피 애니가 그냥 “짧게 이동” 이면 소울라이크가 아닌 거였다. 회피 400ms 중 중반 200ms 를 무적으로 만들어야 한다. 적의 공격 프레임이 이 무적 창 안에 겹치면 데미지 0.
여기서 한 발 더 나간 게 퍼펙트 도지. 무적 프레임이랑 적의 스트라이크가 정확히 겹치면:
- 300ms 슬로모션 창 열림
- 그 창 안 카운터 데미지 x1.5
세키로 패링, 엘든링 swift dodge 가 다 이 매커니즘이라고 한다.
이거 몇 줄로 회피가 그냥 이동이 아니라 “타이밍” 이 되는 거다. 로직상은 별거 아닌데 게임 만족감이 꽤 달라진다.
그리고 하나 더 — 부딪혔다고 죽는건 안됨.
이게 소울라이크의 성격을 결정하는 룰이란다.
몹 몸에 부딪히기만 하는 걸로는 데미지가 발생하지 않는다.
오직 attack window 안에서 지정된 부위 (검, 손, 발) 만 딜을 낸다.
몹 옆에 서 있기만 해도 딜이 들어오면 그 순간 아케이드 게임이 되어버린다는 것. 소울라이크의 그 “내가 결정한 만큼만 결과가 온다” 는 감각, 그게 이 룰 하나에서 나오는 것 같다.
구현은 심플하다. hitbox 기본 데미지를 0으로 두고, 애니 특정 프레임 구간에서만 지정 부위의 데미지를 상향. 창 지나면 다시 0.
마치며
일단 오늘은 앞의 3개 (히트 스톱, 셰이크+플래시, 몹 후딜) 만 붙여봤다.
몇 시간 만에 게임이 다른 게임이 됐다.
밋밋하던 게 갑자기 “쨍” 하고 뭔가 씹히는 느낌.
…아오, 게임 재밌게 만들기가 이렇게 어려운 일이었다니…
새삼, 게임 개발이 진짜 제일 난이도가 높은 영역의 SW 개발이라는 생각이 든다.
멀티플레이가 들어가면 릴레이 서버니, 레이턴시니 생각해야 할 게 또 두 배는 늘어난다.
암튼… 잘 가고…있나..?
마침.