실습 노트
AI 캐릭터 스프라이트 애니메이션: 초기·실패·성공 비교 실습
서류를 들고 걷는 종이 로봇을 6프레임에서 12프레임으로 늘리고, 위치 정렬부터 반대 다리 전진까지 차례로 바로잡은 기록입니다.
홈페이지 히어로에 서류를 들고 걷다가 넘어지는 종이 로봇을 넣었습니다. 처음 만든 스프라이트는 걷기 4장과 넘어짐 2장, 다음 버전은 걷기 6장과 넘어짐 6장이었습니다.
그림 수를 두 배로 늘렸지만 바로 자연스러워지지는 않았습니다. 캐릭터의 크기와 위치가 프레임마다 달라서, 실제 화면에서는 걷는 동작보다 상하좌우 흔들림이 먼저 보였습니다.
아래는 같은 10초 주기로 재생한 초기·실패·성공 버전입니다.
기기에서 동작 줄이기를 사용하고 있다면 세 애니메이션은 첫 프레임에서 멈춥니다.
초기 버전: 6장으로 동작을 나누기
그 전에는 384×384 단일 이미지를 CSS로 위아래 이동시키고 회전시켰습니다. 캐릭터 전체가 넘어지는 표현은 가능했지만 팔과 다리, 눈, 종이는 한 장 안에서 바뀌지 않았습니다.
첫 스프라이트 시트1는 걷기 4장과 넘어짐 2장을 가로 한 줄에 배치했습니다. 한 장짜리 회전보다는 동작이 구분됐지만, 넘어지는 과정이 두 장뿐이라 서 있는 자세에서 바닥 자세로 빠르게 바뀌었습니다.
실패 1: 장수를 늘리자 캐릭터가 달라졌다
걷기와 넘어짐을 각각 6장으로 늘리고, 넘어질 때 눈을 짧은 가로형 감긴 눈으로 바꿨습니다. 생성 중간본에서는 기존 캐릭터의 안테나가 사라졌습니다.
사용자: 안테나 없어짐 ㅜ
프레임 수나 자세만 요청하면 생성 과정에서 캐릭터의 고유 요소가 빠질 수 있었습니다. 이후 프레임을 만들 때는 안테나, 머리와 몸의 비율, 들고 있는 서류, 눈 모양을 같이 확인했습니다.
실패 2: 12장인데 움직임이 더 부산스러웠다
안테나와 눈을 고친 12프레임 버전을 실제 히어로 크기로 재생하자 다른 문제가 보였습니다.
사용자: 됐는데 이미지 크기가 일정치가 않아서, 움직임이 부산스럽네 ㅋㅋㅋ
각 파일의 캔버스는 모두 512×512였습니다. 하지만 투명 배경을 제외한 알파 채널2의 실제 경계를 재보니 걷기 프레임의 위치가 아래처럼 달랐습니다.
| 프레임 | 보이는 폭 | 왼쪽 x | 바닥 y |
|---|---|---|---|
| walk-01 | 245px | 212px | 460px |
| walk-02 | 238px | 153px | 446px |
| walk-03 | 247px | 63px | 446px |
| walk-04 | 230px | 215px | 381px |
| walk-05 | 233px | 155px | 387px |
| walk-06 | 232px | 81px | 387px |
왼쪽 좌표는 63px에서 215px, 바닥 좌표는 381px에서 460px까지 벌어졌습니다. 같은 512×512 이미지라는 정보만 보고 이어 붙이면 캐릭터가 프레임마다 순간이동하는 것처럼 보일 수밖에 없었습니다.
정렬 단계: 포즈와 정렬 오차를 나눠서 처리하기
걷는 자세는 무릎이 굽거나 몸이 펴지면서 높이가 달라집니다. 그래서 모든 프레임의 높이를 억지로 같게 만들지 않았습니다.
- 걷기 6장은 보이는 폭을 240px로 맞췄습니다.
- 가로 중심은 512px 캔버스의 중앙에 놓아 왼쪽 좌표를 136px로 맞췄습니다.
- 발이 닿는 바닥선은 y=460px로 통일했습니다.
- 자세 때문에 생기는 세로 높이 차이는 그대로 남겼습니다.
넘어짐 6장은 프레임마다 폭을 따로 맞추면 회전하는 동안 몸이 커졌다 작아질 수 있습니다. 첫 넘어짐 프레임의 보이는 폭 260px을 기준으로 240 ÷ 260 = 0.923077 배율을 구하고, 여섯 장 모두에 같은 92.3% 배율을 적용했습니다. 바닥선은 y=460px로 맞추되 공중에 뜨는 세 번째 프레임만 y=442px에 두었습니다.
핵심은 모든 숫자를 같게 만드는 것이 아니었습니다. 걷기에서는 중심과 바닥선을 고정하고 자세 차이를 남겼고, 넘어짐에서는 한 배율을 끝까지 유지했습니다.
최종 보정: 다리 교차 프레임 넣기
크기와 위치를 맞춘 v5는 부산스러운 흔들림이 줄었지만, 걷기 6장 중 여러 장의 다리 실루엣이 비슷했습니다. 긴 보폭만 이어져 실제 보행의 중간 동작보다 제자리에서 튀는 인상이 남았습니다.
사용자: 애니메이션 다리가 교차하는 게 없어서 약간어색함
v6에서는 기존의 폭 240px·중심 x=136px·바닥 y=460px 기준을 그대로 유지하면서, 걷기 2·4·6번에 다리가 겹쳐 보이는 통과 자세를 넣었습니다. 긴 보폭과 교차 자세가 번갈아 나타나도록 실루엣의 차이를 키운 것입니다. 넘어짐 6장은 눈·안테나·배율이 이미 맞아 기존 프레임을 그대로 사용했습니다.
다만 좌우 다리의 순서를 해부학적으로 완전한 보행 주기로 다시 그린 것은 아닙니다. 이번 보정의 범위는 실제 표시 크기에서 빠져 있던 교차 자세를 보충하고, 기존 정렬 기준을 깨지 않는 데까지입니다.
다시 실패: 반대 다리 전진이 없었다
v6를 다시 보니 1·3·5번의 긴 보폭은 같은 다리가 앞으로 나온 자세였습니다. 2·4·6번에 교차 자세가 있어도, 접지 자세에서 반대 다리가 앞으로 나오지 않으면 한쪽 다리만 반복해서 내미는 동작으로 보입니다.
사용자: 반대다리가 앞으로 나온 그림이 없는데 되는겨?
맞는 지적이었습니다. v6는 교차 자세를 추가한 보정본이지, 양쪽 다리가 번갈아 전진하는 보행 주기까지 완성한 버전은 아니었습니다.
v7은 옆모습에서도 두 다리의 순서를 추적할 수 있도록 뒤쪽 다리만 회색으로 구분했습니다. 1번에서는 흰 다리가 앞으로 나오고, 2번에서 두 다리가 교차한 뒤, 3번에서는 회색 다리가 앞으로 나옵니다. 4번 교차 자세를 거쳐 5번에서 다시 흰 다리가 전진합니다.
여섯 장에는 모두 같은 92% 배율을 적용하고, 가로 중심은 x=256px, 바닥은 y=460px로 맞췄습니다. 긴 보폭과 교차 자세의 실루엣이 달라 보이는 폭은 226~285px로 달라지지만, 캐릭터 몸체가 프레임마다 확대·축소되지는 않습니다. 넘어짐 6장은 기존 성공본을 그대로 사용했습니다.
12장을 한 파일로 묶기
정리한 12장은 4열×3행, 2048×1536 크기의 WebP 한 장으로 묶었습니다. 브라우저에서는 124×124 영역만 열어두고 큰 이미지를 이동시켜 한 프레임씩 보여줍니다.
| 버전 | 장 | 배열 | 파일 |
|---|---|---|---|
| 초기 v3 | 6 | 6×1 | 약 152KB |
| 실패 v4 | 12 | 4×3 | 약 252KB |
| 정렬 v5 | 12 | 4×3 | 약 264KB |
| 교차 보정 v6 | 12 | 4×3 | 약 243KB |
| 성공 v7 | 12 | 4×3 | 약 230KB |
.paper-bot-sprite {
width: 400%;
height: 300%;
animation: paper-bot-frames 10s steps(1, end) infinite;
}
가로로 한 칸 이동할 때는 translateX(-25%), 세로로 한 줄 이동할 때는 translateY(-33.3333%)를 사용합니다. 실행 화면은 Cloudflare R23의 WebP 한 장만 요청하고, 프레임 전환은 CSS가 처리합니다. PNG 원본과 실행용 WebP는 v3부터 v7까지 버전 경로로 나눠 보관했습니다.
다음 작업에서 바로 쓸 체크리스트
- 생성 전에 안테나, 눈, 들고 있는 물건처럼 캐릭터를 구분하는 요소를 적습니다.
- 배경을 투명하게 만든 뒤 각 프레임의 알파 경계를 측정합니다.
- 걷기는 보이는 폭, 가로 중심, 바닥선을 맞추고 포즈 높이는 남깁니다.
- 긴 보폭 사이에 다리가 겹치는 통과 자세가 있는지 실루엣으로 확인합니다.
- 옆모습의 두 다리가 같은 모양이라면 뒤쪽 다리에만 옅은 색을 써서 어느 다리가 앞으로 나오는지 추적합니다.
- 첫 접지 자세와 다음 접지 자세에서 서로 반대 다리가 전진했는지 확인합니다.
- 넘어짐은 첫 프레임에서 구한 하나의 배율을 전체에 적용합니다.
- 스프라이트로 묶기 전에 124px 데스크톱과 96px 모바일 크기에서 먼저 재생합니다.
- 실패 파일을 덮어쓰지 않고 버전 경로로 남겨 비교할 수 있게 합니다.
prefers-reduced-motion에서는 애니메이션을 끄고 첫 프레임을 보여줍니다.
이번 작업에서는 장수를 늘리는 것, 좌표 기준을 맞추는 것, 교차 자세를 넣는 것, 양쪽 다리를 실제로 번갈아 내미는 것이 서로 다른 문제였습니다. 위치가 흔들리는 v4, 정렬을 마친 v5, 교차 자세만 넣은 v6, 반대 다리 전진까지 확인한 v7을 남겨 각 수정 단계의 차이를 확인할 수 있게 했습니다.
(1) 스프라이트 시트(Sprite Sheet) — 애니메이션에 필요한 여러 프레임을 한 이미지 안에 배열한 파일입니다. 화면에서는 정해진 영역만 잘라 보여주고 이미지 위치를 바꿔 다음 프레임으로 전환합니다.
(2) 알파 채널(Alpha Channel) — 이미지 픽셀의 투명도를 담는 정보입니다. 투명 픽셀을 제외한 경계를 측정하면 캔버스 크기가 아니라 실제 캐릭터가 차지하는 영역을 구할 수 있습니다.
(3) Cloudflare R2 — 이미지 같은 파일을 저장하고 웹 주소로 제공할 수 있는 객체 스토리지입니다.