TECHARTNOMAD | MAZELINE.TECH

TECH.ART.FLOW.IO

[번역] UE4 UE5 스켈레탈 애니메이션 고급 로코모션 시스템 카메라 관리

jplee 2026. 7. 27. 03:32

저자: DarkFlameMaster

최근 언리얼 엔진의 스켈레탈 애니메이션 관련 지식을 공부하고 있는데, 가르치면서 배운다는 마음으로 여기에 애니메이션 관련 글을 써 보면서 배운 걸 바로바로 풀어내 보려 한다.

(이 글에서는 대화형 글쓰기를 시도해 보았다. 독자가 읽는 재미도, 내가 쓰는 재미도 살려 보고 싶어서 《중2병이라도 사랑이 하고 싶어!》의 두 주인공 입을 빌렸다. 앞부분에 짧은 배경 설정이 있으니, 후기를 먼저 읽어 보길 추천한다.

1.서막

석양이 부드럽게 내려앉고, 가을바람이 살랑인다.

노을의 잔광이 은행학원 운동장 위에 쏟아지며, 체육 동아리 학생들의 훈련하는 모습을 비춘다. 하교 종이 유려하게 울리자 그 소리에 놀란 새들이 교정 한구석 큰 용나무 주위를 위아래로 날아오르고, 맑은 울음소리가 여기저기서 이어지며 종소리에 화음을 더한다.

시가현의 도로에는 차들이 오가고, 작은 도시가 하루 종일 지친 몸을 겨우 굴려 온 끝에 맞이하는 하루의 마침표가 내려앉는 시각이다. 직장인들은 각자의 교통수단에 몸을 맡긴 채, 녹초가 된 몸을 억지로 일으켜 집으로 향한다.

그 오가는 인파 속에서, 교복을 입은 소년과 소녀가 나란히 걷고 있다. 유타와 릿카. 그들은 시가현에서 언리얼 엔진을 가르치는 유일한 고등학교——은행학원의 1학년이다.

그중 소녀는 멀리 보이는 풍차를 향해 팔을 높이 들고, 입속으로 무언가를 중얼거리고 있다……

릿카: 하아…… 아아! 어둠의 힘으로, 풍차를 돌리거라!

유타: 정말 바보라니까…… 하아. 릿카, 오늘 학교에서 배운 고급 로코모션 시스템의 카메라 관리, 제대로 듣고 있었어?

릿카: 으응… 음……

유타: 그럴 줄 알았다. 어젯밤에 또 새벽에 돗슈와 무슨 비밀 작전을 하러 간 거지?

릿카: ……! 흥! 사왕진안의 힘은 관리국이 무의식중에 내보내는 뇌파를 수신해서, 적의 지식을 훔쳐 낼 수 있다고! 고작 고급 로코모션 시스템 따위…… 아야!

유타는 릿카 머리를 내려친 손날을 거두며 한숨을 쉰다: 이대로면 네가 낙제할 것 같아서 걱정이야. 하교길에 시간이 있으니까, 내가 살짝 알려 줄게. 자, 오늘 수업 때 적어 둔 노트야. 일단 받아 보고, 이따 내 설명과 맞춰 가면서 이해해 봐.

릿카: 헤헤, 역시 유타가 나한테 제일 잘해 준다니까~

2.ALS의 카메라 관리 아이디어 정리하기

유타: 고급 로코모션 시스템의 카메라 관리는 전통적인 방식과 달라. 캐릭터 블루프린트 안에 넣어 두던 카메라와 스프링 암을 지워 버리고, 대신 플레이어 카메라 매니저(PlayerCameraManager)와 카메라용 애니메이션 블루프린트를 직접 만들어서, 플레이어 컨트롤러가 그 카메라 매니저 클래스를 쓰도록 하거든. 왜 이렇게 하는지 알아?

릿카: 음…… 생각해 볼게…… 카메라는 플레이어의 눈처럼, 플레이어 대신 이 세상을 보는 거니까. 현실에서 움직일 때 눈이 보는 것의 변화를 카메라가 흉내 내면 게임의 사실감이 올라가지. 예를 들어 전력 질주할 때 몸의 무게중심이 낮아지면서 눈의 위치도 같이 내려가고…… 여기까지는 맞지?

(ALS는 캐릭터가 전력 질주할 때 카메라 높이를 30 내려 준다)

(ALS는 캐릭터가 전력 질주할 때 카메라 높이를 30 내려 준다)

유타: 응, 거의 맞아. 그런데 그건 “왜 ALS가 카메라 관리를 중요하게 여기고, 스프링 암에 카메라만 대충 꽂아 두지 않는가”에 대한 이야기고. 그럼 왜 ALS는 카메라를 따로 분리해 냈을까?

릿카: 흠흠! 그건 당연히 카메라에 대한 조작이 점점 더 복잡해지기 때문이겠지. 캐릭터 블루프린트 안에 다 넣어 두면, 카메라 조작을 고칠 때마다 캐릭터 블루프린트를 건드려야 해서 카메라와 캐릭터 블루프린트가 강하게 결합돼 버려. 차라리 카메라를 독립된 모듈로 관리·유지하는 편이 낫고, 캐릭터 블루프린트는 인터페이스로 데이터만 넘겨 주면 되잖아.

유타: 잘했어. 게다가 씬 속 모든 캐릭터에 카메라가 필요한 것도 아니야. 플레이어가 조종하는 캐릭터만 필요하거든. 카메라를 캐릭터 몸에서 “벗겨” 내면, 어떤 캐릭터에 카메라 컴포넌트를 붙여야 할지 고민할 필요도 없어져. 그건 카메라가 알아야 할, 고민해야 할 일도 아니고. 카메라는 자기 자신의 변환을 제어하는 로직만 알면 충분하거든.

살수차가 크게 음악을 틀며 두 사람 옆을 천천히 지나간다. 그 때문에 둘의 대화에 잠깐의 틈이 생긴다.

릿카가 살짝 고개를 들어, 하늘 끝에서 물속으로 가라앉는 석양을 바라본다: 유타, 석양 진짜 예쁘다.

유타: 그렇지. 그야말로 석양 한 줄기 물 위에 펼쳐지고, 강물의 반은 푸르고 반은 붉구나…… 콜록콜록, 화제 돌리려 하지 마. 복습 계속한다!

릿카: 알겠어……

유타: 카메라의 움직임은 애니메이션과 아주 밀접하게 연결돼 있어. 캐릭터가 지금 어떤 애니메이션을 하고 있는지에 따라 카메라를 어떻게 조작할지 정해지거든. 생각해 봐. 그냥 “캐릭터가 전력 질주를 시작한다”는 노티파이만 하나 붙여서 카메라 매니저에 보내고 살짝 내려가게 한 다음, “캐릭터가 전력 질주를 멈췄다”고 다시 노티파이를 보내는 식으로 계속하면, 금방 카메라 매니저 안에 온갖 노티파이와 이벤트가 잔뜩 쌓여 버릴 거야. 그렇게 되면 유지·확장도 어렵고, 개방-폐쇄 원칙에도 어긋나.

릿카: 그럼 어떻게 해야 해? 중간 레이어를 하나 둘까?

유타: 맞아. 결합을 푸는 좋은 방법이 바로 중간 레이어를 두는 거지. ALS 작성자의 아이디어는 그 중간 레이어를 애니메이션 블루프린트가 맡게 하는 거야.

방금 말했듯이 카메라 움직임은 애니메이션과 밀접하니까, 애니메이션 전환이 곧 카메라 움직임 전환이라고 해도 과언이 아니야. 그럼 캐릭터처럼 카메라에도 애니메이션 블루프린트를 하나 만들어 주면 어떨까? 카메라도 캐릭터의 걸음걸이(Gait), 자세(Stance), 회전 모드(RotationMode), 이동 행동(MovementAction)을 받아서, 캐릭터 애니메이션 블루프린트처럼 상태 머신을 짜고 상태를 전환하게 하는 거지.

릿카: 그런데 캐릭터 애니메이션 블루프린트에서는 애니메이션 시퀀스를 재생해서 캐릭터 동작을 바꾸잖아. 그럼 카메라의 애니메이션 블루프린트는? 카메라용 애니메이션 시퀀스도 만들어야 해? 카메라의 달리기 애니메이션, 카메라의 Idle 애니메이션…… 상상이 안 돼. 머리가 아파, 유타——

유타: 바보야! 카메라는 플레이어가 세상을 보는 눈일 뿐이야. 월드 안에는 그 위치와 회전을 나타내는 점 하나만 있으면 돼. 캐릭터가 앞으로 갈 때는 앞으로의 이동이랑 자연스러운 걷기 포즈가 필요하지만, 카메라는 그 점만 앞으로 옮기면 되는 거잖아?

릿카: 오오~! 역시 DarkFlameMaster! 그럼 애니메이션 상태 머신의 상태 노드에서 “카메라 애니메이션 시퀀스” 같은 걸 재생할 필요 없이, 카메라만 살짝 움직이고 돌리면 된다는 거지?

유타: 맞아. 각 상태 노드마다 카메라에 어떤 처리를 할 수 있어. 시야각을 조금 키우거나, 카메라를 조금 올리거나, 플레이어를 따라가는 속도를 늦추거나, 아래로 조금 기울이거나…… 그게 바로 캐릭터가 해당 상태에 있을 때 카메라가 해야 할 일이야. 예를 들어 달릴 때는 카메라를 조금 아래로 누르고, 플레이어를 따라가는 속도를 살짝 느리게 해 볼 수 있지.

그런데 카메라 애니메이션 블루프린트 자체는 카메라 움직임을 직접 관장하지 못해. 릿카, 우리가 카메라에 시키고 싶은 이 변환값들을 플레이어 카메라 매니저에 어떻게 넘겨 주는 게 좋을까?

릿카: 그건…… 저건…… 유타 노트를 좀 볼게……

릿카: 흠흠! 알겠다, 커브지! 맞지~?

유타: 맞아. 애니메이션 블루프린트와 로직 블루프린트 사이에서 커브로 데이터를 넘기는 방식은, ALS의 제자리 회전에서도 썼어. 그때 쓰던 커브가 RotationAmount였지. 기억나지? 봐, 이 그림처럼 카메라 본의 커브 값만 수정하면 돼.

릿카: 이해했어. 그런데 유타, 이건 좀 우회하는 느낌 아니야? 카메라 애니메이션 블루프린트도 결국 캐릭터의 운동 상태에 따라 다른 카메라 변환을 처리하는 거면, 아예 카메라 커브 값 수정을 캐릭터 애니메이션 블루프린트에 통합해 버리면 안 돼?

자세히 말하면, 먼저 캐릭터 스켈레톤에 카메라용 오프셋 커브들을 추가하고, 캐릭터 애니메이션 블루프린트의 각 상태 노드에서 카메라 오프셋 커브 값을 설정한 다음, 카메라 매니저가 캐릭터 애니메이션 블루프린트에서 그 커브 값을 읽어 오게 하는 거지.

그러면 카메라 애니메이션 블루프린트 쪽에 비슷한 상태 머신 구조를 또 만들 필요도 없고, 나중에 수영이니 비행이니 새 이동 모드를 넣을 때도 캐릭터 애니메이션 블루프린트에 로직 하나 넣고, 또 카메라 애니메이션 블루프린트에 로직 하나 더 넣는 일을 안 해도 되잖아. 아니야?

유타: 그 질문 괜찮네. 릿카도 제대로 생각하고 있었구나.

릿카: 에헤헤~

유타: 음…… 나도 확신까지는 없어. 내 이해 범위 안에서 한번 대답해 볼게. 내일 친구들한테 이 문제를 어떻게 보는지 물어봐 줄게.

우선 ALS가 카메라를 캐릭터 블루프린트에서 “벗겨” 낸 이유는, 카메라 기능을 상대적으로 독립시켜서 특정 캐릭터 타입에 의존하지 않게 하려는 거였어. 그런데 네가 말한 것처럼 카메라 오프셋 커브를 특정 스켈레톤에 박아 넣는 방식이면, 새 스켈레톤을 가진 새 캐릭터가 올 때마다 그 스켈레톤에 카메라 커브를 또 만들고, 그 캐릭터 애니메이션 블루프린트에 카메라 오프셋 수정 로직을 또 써야 하지 않아?

릿카: 으음……

유타: 그렇지. 그러면 카메라와 캐릭터를 서로 독립시키려던 디커플링 취지에도 어긋나고, “코드 복붙” 가능성도 커져. 디자인 패턴에서 제일 꺼리는 게 바로 Ctrl+C, Ctrl+V야. 뭐, 네 방식대로 안 해도 카메라 애니메이션 블루프린트 쪽에도 비슷한 “복붙”이 생기긴 하지만. 그 부분은 솔직히 나도 아직 확신이 없어.

릿카: 응응, 유타. 알겠어.

3.카메라 애니메이션 상태 머신 만들기

릿카: 저기, 유타. 나 목말라~

유타가 릿카를 흘겨보며 한숨을 쉰다: 정말이지, 내가 한참 설명했는데 네가 나보다 먼저 목마르다고?

그래도 릿카 말에 유타도 목이 좀 마른 느낌이 들었다. 설명을 잠시 멈추고 길가 자판기에서 음료 두 캔을 산 뒤, 릿카 병뚜껑을 열어 건네 주고 자신도 한 모금 마셔 목을 축였다.

유타: 지금부터 말할 내용은 사실 ALS랑 조금 달라. 내가 이렇게 하는 편이 더 낫다고 생각해서 바꾼 부분이야. 봐, ALS 원본은 이렇게 되어 있어:

이 그림을 보면, 걷기·달리기·전력 질주 상태에서 카메라에 가하는 보정이 섞여 있어. 카메라 위치 오프셋과 카메라 따라가기 지연, 두 축으로 나뉘고 각각 XYZ 세 축으로 또 나뉘지. 이 여섯 값 중 같은 값이 꽤 많아. 그래서 나중에 카메라를 조금 당기고 싶어서 Camera Offset X를 -200으로 바꾸고 싶으면, 하나하나 다 고쳐야 하잖아?

이 상태 노드 안에서는 걷기·달리기·전력 질주뿐 아니라 서기·앉기 두 자세까지 섞고 있으니까, 실제로 Camera Offset X 여섯 개를 전부 하나씩 고쳐야 해.

릿카: 맞아. 고칠 곳이 너무 많아서 불필요한 작업량이 늘고, 실수할 확률도 올라가.

유타: 그렇지. 그래서 나는 ALS 캐릭터 애니메이션 블루프린트처럼, 학교에서 왕 선생님이 말한 “양파 패턴”을 따라 각 레이어의 디테일 블렌드를 상태 머신으로 만들어 보면 어떨까 생각했어.

봐, 이게 오늘 내가 한 숙제야. 아직 다 못 했고, 지금은 걷기·달리기 블렌드랑 시점 전환, 이 두 레이어만 섞어 둔 상태야.

릿카: 유타, 걷기·달리기 블렌드 상태 머신 좀 보여 줘.

유타: 좋아. 다만 오늘은 게을러서 Sprint는 아직 안 넣었어. 걷기랑 달리기만 먼저 해 뒀지.

봐, Walk와 Run 상태 노드 사이를 이렇게 전환하는 건, ALS 원본이 “블렌드 포즈(ALS_Gait)” 노드로 만든 효과랑 사실상 같아.

그리고 이게 Run 상태 노드 내부야. 앞에서 커브 이야기할 때 보여 준 것 같기도 하고.

이렇게 해 두면, 갑자기 기본 카메라 설정을 바꾸고 싶어서 기본 CameraOffsetZ를 수십 단위로 올리고 내려도, 커브 수정 노드를 하나하나 손댈 필요가 없어. 다른 상태 노드에서는 커브 적용 모드를 전부 **더하기(Add)**로 두었거든. 기본값이 어떻게 바뀌든 여기는 손댈 일이 생기지 않아.

릿카: ViewModeCameraTransformOffset 상태 머신도 보고 싶어.

유타: 음…… 우리 거의 집 앞이야. 그건 지금 안 보여 줘도 될 것 같아. 시간이 부족하거든. 그 안에는 이미 걷기·달리기를 섞어 둔 캐시 포즈 LocomotionCameraOffset만 쓰고 있을 뿐이야. ALS가 애니메이션 블루프린트에서 쓰는 생각과 같아. 양파 패턴을 잊었다면 왕 선생님

4.플레이어 카메라 매니저의 몇 가지 디테일

릿카: 엥? 그럼 유타는 플레이어 카메라 매니저를 구체적으로 어떻게 만드는지 안 알려 주는 거야? 야, 유타, 알려 줘, 알려 달라니까~

유타: 진짜 시간이 없어. 그리고 나는 원래 “왜인가”를 생각하게 도와 주고 싶었지, “무엇인가”를 바로 알려 주려던 게 아니야. 구체 조작은 교과서 보고 해. 대부분은 이해하기 어렵지 않아서 굳이 말할 게 많지 않아. 신호 기다리는 이 짧은 시간에 마지막 디테일만 말해 줄게.

릿카: 정말이지~! 유타, 인색해.

유타: 첫 번째는 이 “축 독립 카메라 래그 계산”…… 번역이 정확하진 않을 수 있어. 기능으로 보면 결국 카메라 축 위치를 커브에 설정된 래그 속도에 맞춰 보간하는 거야. ALS 원본에서는 카메라 축 위치를 다음 프레임 카메라 회전의 역회전으로 돌린 뒤 보간하고, 다시 원래대로 돌려놓지. 이 단계는 개인적으로 꼭 필요하진 않다고 느껴져.

봐, 내 숙제에서는 이 회전·역회전 단계를 지웠는데, 테스트해 보니 잘 돌아가더라고. 다만 ALS를 깊게 못 읽어서 이 단계의 진짜 의도를 못 잡은 걸 수도 있어.

릿카: 오오, 나도 집에 가서 해 볼게.

유타: 두 번째는 ALS가 캐릭터 변환을 PivotTransform, 즉 피벗 변환으로 쓰는 부분이야. 내 느낌으로는 “카메라를 따라가게 할 목표를 캐릭터로 설정한다”고 이해하면 될 것 같아. 그리고 피벗의 기본 위치에 사람이 설정한 오프셋을 더하면, 카메라가 목표로 삼아야 할 위치가 나오지. ALS는 이 오프셋을 PivotOffset과 CameraOffset으로 나눴어. 전자는 캐릭터의 회전 방향을 기준으로 보정하고, 후자는 카메라 다음 프레임의 목표 회전 방향을 기준으로 보정하지.

릿카: 응응, 그다음은?

유타: 마지막은 스프링 암의 메시 관통 방지 기능을 흉내 내는 부분이야. 이건 내가 숙제에 적어 둔 노트 보면 되고, 더 떠들진 않을게.

그 말을 끝으로 둘은 마침 유타 집 앞에 도착했다. 릿카는 위층에 살아서, 여기서 헤어져야 한다.

릿카가 얼굴이 빨개진 채 우물거리며 말한다: 오늘 고, 고마워, 유… 유…… 고마워 DarkFlameMaster! 그래도 사왕진안이 최강이야!

유타: 그 이름 부르지 마! 쪽팔리잖아! 바보야!

후기

최근에 예전에 쓴 글들을 다시 읽어 보니, 어느새 나도 모르게 고정된 문체가 잡혀 있었다——그리고 그 문체가 썩 마음에 들지도 않았다. 그래서 새로운 문체를 탐색해 보고 싶었다——어떻게 하면 글이 엄밀하면서도 최대한 재미있고, 독자가 부담 없이 읽을 수 있을까.

몇 해 전 읽었던 청제 선생님의 《대화로 배우는 자료구조》와 《대화로 배우는 디자인 패턴》이 떠올랐다. 그 두 교재는 전문성을 잃지 않으면서도 충분히 재미있어서 끝까지 읽게 만들어 주었다. 그중 《대화로 배우는 디자인 패턴》은 대화 형식으로 수업을 전개했고, 블로그에서 발전한 책이었다. 그래서 그 스타일을 한번 흉내 내 보기로 했다.

그런데 대조와 소채를 그대로 쓰거나, 사제 관계를 새로 짜면 설정 깔아 주는 데 시간이 꽤 들 것 같았다. 이 글은 결국 블로그라서 책처럼 설정을 한 번만 써 두고 끝낼 수도 없다. 내 시리즈를 처음 보는 사람이 늘 있을 테니, 글마다 설정을 길게 소개할 수도 없다. 설정을 너무 짧게 쓰면 또 그 맛이 안 나고 몰입이 안 된다.

그래서 내가 좋아하는 애니메이션 《중2병이라도 사랑이 하고 싶어!》의 남녀 주인공 인물과 배경 설정을 그대로 빌려 왔다. 참고로, 내 즈후 이름 DarkFlameMaster도 남주인공이 중2 시절에 스스로 붙인 “법호”에서 왔다.

이 글은 형식과 문체를 바꾸다 보니, 평소 글보다 시간과 정력이 훨씬 더 들었다. 게다가 마음이 많이 조마조마했다. 누군가는 좋아해 줄까, 누군가는 오히려 이런 형식이 더 읽기 어렵다고 느낄까, 아니면…… 아무튼 독자 여러분께서 공로까지는 아니더라도 고생은 봐 주시길, 좋아요를 많이 눌러 주셔서 내가 글을 “더 재미있고, 더 읽기 쉽게” 만들려고 들인 노력을 응원해 주셨으면 한다. 동시에 어떤 피드백이든, 긍정적이든 부정적이든, 구체적일수록 좋다. 그래야 글쓰기 방식과 스타일을 어떻게 다듬을지, 지금 이 시도가 맞는 방향인지 알 수 있으니까.

또한 인단 선배의 조언도 받아들여, 이번 글의 이미지 수는 이전보다 확실히 많다.

마지막으로, 필자 수준이 부족해 글에 틀린 곳이나 빠진 곳이 있을 수밖에 없다. 독자 고수 여러분의 따끔한 지적과 가르침을 부탁드린다.

PS: 글 속에 나온 “숙제”는 지금 친구들과 함께 만들고 있는 소울류 전투 프레임워크다. 그중 애니메이션 부분은 내가 맡았고, ALS 방식을 참고해 내 이해에 따라 군더더기를 줄이거나 조금 개선했다. 어느 정도 다듬어지면 글로 풀어 볼까 생각 중이다. 관심 있는 독자가 있는지가 관건이다. 관심 있으면 댓글로 한마디 남겨 달라. 사람이 많으면 그 구덩이를 메우러 가겠다.

PS: 겸사겸사 여기서 필자가 막 개설한 UE 스켈레탈 애니메이션 교류방도 살짝 홍보해 본다: 916274600, 여러 고수님들의 방문과 가르침을 환영한다.

같은 지붕 아래 살면서,


원문
(76 封私信 / 38 条消息) UE4 UE5 骨骼动画 高级运动系统 摄像机管理 - 知乎