Live2D / VRM 캐릭터 애니메이션
이 스킬은 Live2D와 VRM 캐릭터를 동시에 지원하는 데스크 펫(하단 '출처 및 유지 관리' 참조)에서 비롯되었습니다. 사용된 모델로는 공식 예제, VTube Studio용 모델, VRChat에서 변환된 VRM이 있습니다. 아래의 방법들은 모두 테스트되고 측정되었거나 사용자가 검토 및 수정한 것입니다.
두 종류의 캐릭터에 적용되는 세 가지 원칙
- 프로그래매틱 레이어와 모션 클립은 서로를 덮어씁니다. 매 프레임 누가 먼저 계산되고 누가 나중에 쓰여지는지가 사용자에게 보여지는 것을 결정합니다. 거의 모든 '깜빡임', '손을 내림', '머리가 움직이지 않음' 문제는 여기서 발생합니다:
- Live2D:
beforeModelUpdate에 배치된 프로그래매틱 중첩 값은 물리에 들어가지 않아 머리카락과 몸이 따라 움직이지 않습니다.physics.evaluate을 감싸서 물리 이전에 중첩해야 합니다. - VRM: three.js의
AnimationMixer가 한 프레임에서 혼합한 값이 이전 프레임과 같으면 본에 쓰지 않습니다. 매 프레임 프로그래매틱으로 설정된 자세와 호흡이 클립이 '멈춘' 부분에서 드러납니다. 재생 중인 클립이 쓰고 있는 본(clip.tracks의 노드 이름 기준)은 건너뛰어야 합니다. 일시 정지 시에도 마찬가지로, 프로그래매틱 자세 재작성을 중지해야 합니다.
- Live2D:
- 모션 파일을 수정하지 말고, 그 위에 프로그래매틱 레이어를 추가하세요. 손으로 만든 키프레임이나 AI가 만든 모션은 종종 몇 개의 본만 움직입니다(손을 흔드는 것은 팔만 움직임) . 마치 나무 인형 같습니다. 클립 이후에 프로그래매틱으로 계산된 '드라이빙'(어깨는 따라 올라가고, 상체는 양보하며, 손목은 지연되고, 머리는 반 템포 늦게 움직임) 레이어를 추가하되, 클립 자체가 쓴 본에는 중첩하지 마십시오. 한 번 만들어두면 모든 모션에 혜택이 가며, 켜고 꺼서 비교할 수 있습니다.
- 검증은 눈으로 하지 말고 프레임별 기록으로 하세요. 애니메이션 문제는 한두 프레임에만 나타나는 경우가 많아 육안으로 수정 여부를 확인하기 어렵습니다. 해당 본(파라미터)이 그려질 때의 값을 매 프레임 기록하고(렌더링 후, 또는 Live2D의
beforeModelUpdate에서 읽음), 수정 전과 후를 각각 기록하여 비교합니다. 그런 다음 두 개의 다른 모델에서 스크린샷을 찍어 확인합니다.
언제 어디를 읽을지
| 해야 할 일 | 읽을 곳 |
|---|---|
| Live2D: 로딩, 파라미터 쓰기, 물리, 대기, 모션, 고정, 표정 | references/live2d.md |
| VRM: 프로그래매틱 포즈와 클립, 드라이빙 레이어, 모션 캡처 클립, 표정, 스프링 본, 투명 창 | references/vrm.md |
| VRM: 모션과 표정 조합, 손 모양과 손목, 손이 몸에 닿는 IK, 인터럽트 시 손 놓침 방지, 다리 한계, 눈과 머리 추종, 키프레임 보간 및 분할 | references/vrm.md 19–31번 항목 |
| AI가 표정이나 모션을 생성하거나 수정하도록 하기 | references/ai-motion.md |
| 음악에 맞춰 고개 끄덕이기, 말할 때 머리 움직이기 | references/live2d.md 16번 항목, references/vrm.md '비트 따라가기' |
가장 흔한 함정 (먼저 이 항목들을 확인하세요)
| 현상 | 원인 | 수정 방법 |
|---|---|---|
| Live2D가 'Could not find Cubism runtime' 오류를 내거나 그려지지 않음 | 로딩 순서가 잘못됨 | Cubism Core → 렌더 파이프라인 모듈 등록 → PixiJS Application.init() → 모델 |
| Live2D 파라미터를 읽었는데 58, null 같은 이상한 값이 나옴 | 문자열 ID를 직접 전달함 | 먼저 internalModel.getIdSafe(name)으로 핸들로 변환 |
| Live2D 머리가 따라 움직이지 않음 (VTube Studio 모델) | ParamAngle*이 물리의 출력이어서 쓰면 덮어써짐 | physics3.json을 읽고, 대신 그것의 입력 파라미터에 씀 |
| Live2D 머리만 흔들리고 머리카락, 몸은 움직이지 않음 | 중첩이 물리 이후에 이루어짐 | physics.evaluate을 감싸서 그 이전에 추가 |
| Live2D가 서서 전혀 움직이지 않음 | VTube Studio 모델에 제대로 된 Idle이 없음 | 프로그래매틱 대기: 머리, 몸체에 세 개의 느린 사인파 + 호흡, 표준 파라미터만 씀 |
Live2D stopAllMotions 후에 다시 스스로 움직이기 시작함 | 엔진이 모션이 없다고 판단하여 Idle을 다시 재생함 | motionManager.groups.idle을 존재하지 않는 그룹으로 설정하고 breath를 중지 |
| VRM 손 키프레임 모션이 멈춘 부분에서 손이 내려가고, 시작과 끝에서 깜빡임 | mixer가 변하지 않은 값을 쓰지 않아 프로그래매틱 자세가 드러남 | 프로그래매틱 포즈가 클립이 쓰는 본을 건너뛰도록 함 |
| VRM 일회성 모션 종료 시 한 프레임 점프 | clampWhenFinished=false일 때 mixer가 finished 이전에 action을 닫음 | clampWhenFinished = true로 설정하고 fadeOut 사용 |
| VRM 모션 캡처 모션이 매우 넓게 서고, 시작 시 움찔하며, 치마가 휘날림 | 클립에 엉덩이와 다리 트랙이 포함됨 | 변환 시 엉덩이와 다리 트랙을 삭제하고 상반신만 사용 |
| VRM 치마가 허벅지에 파고들고, 충돌 보조선에 공이 한두 개만 보임 | 충돌체가 스프링 체인의 충돌 그룹에 등록되지 않음 (three-vrm은 등록된 것만 인식) | 표준 골격에 따라 엉덩이 아래 체인에 다리용 캡슐을 추가; 엉덩이가 한 프레임에 점프하지 않도록 함(references/vrm.md 15번 항목) |
| VRM 클립에 쓴 표정이 보이지 않음 | 매 프레임 상태 표정, 깜빡임, 입 모양이 덮어씀 | 클립은 본만 쓰도록 함 |
| 작은 크기에서 표정이 잘 안 보임 | 표정 파일이 아주 일부분만 수정함 | 각 감정에 추가 파라미터 레이어를 더함 (눈을 가늘게 뜸, 얼굴 붉힘, 머리 기울임, 입꼬리) |
| VRM 모션 중에 얼굴에 표정이 없음 | 표정이 상태에만 따라가고 모션과 연결되지 않음 | 모션 옆에 mood + beats를 작성하고 모션 가중치에 따라 혼합(references/vrm.md 25번 항목) |
| 모션이 눈을 감거나 입을 벌려야 하는데 모델 자체의 '졸림'이나 '웃음'이 막음 | 표정의 overrideBlink / overrideMouth가 block임 | 그 순간에 이러한 표정을 억제함 (26번 항목) |
| VRM 한쪽 눈 깜빡임이 보이지 않음 | blinkLeft/blinkRight가 형태 키에 바인딩되지 않음 | 두 눈을 함께 가늘게 뜨는 것으로 대체 (27번 항목) |
| VRM 한 모션이 다른 모션을 중단할 때 손이 내려갔다가 다시 올라옴 | 새 모션이 기본 자세에서 시작하여 크로스 페이드 중에 기본 자세를 통과함 | 새 모션 중 현재 상태와 가장 가까운 지점부터 시작 + 중단 지점에서 전환 (19번 항목) |
| VRM 모션 캡처 손가락이 곧게 펴지거나 주먹을 쥠; 손 키프레임 모션에서 손가락이 항상 반쯤 쥐어짐 | 리타겟팅된 손가락 / 모션이 손가락을 쓰지 않음 | 모션 캡처 손가락을 제거하고, 모션에 손 모양을 씀 (22, 23번 항목) |
| 턱 괴기, 입 가리기, 하트 만들기가 체형이 다르면 위치가 맞지 않음 | 각도만 씀 | 본과 메시를 기준으로 실시간으로 목표를 계산하고, 2-관절 IK 사용 (24번 항목) |
| 춤추기가 끝나면 발이 한 프레임 점프 | 다리 IK가 페이드아웃 시작 프레임에 바로接管 | IK가 다리 모션의 가중치를 따라 천천히接管하도록 함 (20번 항목) |
| 무릎이 반쯤 구부러지고, 편안한 다리가 너무 많이 굽혀짐 | 여러 레이어의 엉덩이 오프셋이 중첩됨 | 무릎 한계 설정, 엉덩이 굽힘을 반으로 줄임; 발뒤꿈치를 들면 오히려 더 굽혀짐 (21번 항목) |
| VRM 눈이 계속 카메라를 빤히 바라봄 | lookAt이 카메라를 향하고 있어, 고개를 돌리면 눈이 반대 방향으로 돌아감 | 모션이 고개를 돌릴 때 시선을 따라가고, 고개 돌릴 때 깜빡이며, 작은 눈 움직임 추가 (28번 항목) |
| 손 키프레임 모션이 끊기고 부드럽지 않음 | 각 키프레임 구간이 양쪽 끝에서 느리고, 각 키프레임의 속도가 0임 | 단조로운 3차 스플라인 + 각 구간 키프레임 오프셋 (29번 항목) |
| 기지개 켜기, 손 들기가 팔을 양옆으로 쭉 뻗어 올라가거나 / 옆으로 수평으로 뻗음 | 주먹 쥐기, 팔뚝 접기 등의 구간이 없음; 비틀기와 팔 들기가 분리되지 않음 | 구간별로 재작업, 비틀기는 문지방에서만 (30번 항목) |
| 한가할 때 체중 이동 시 상체 전체가 한쪽으로 기움 | 무릎 한계가 엉덩이 기울기를 줄였지만, 허리와 가슴은 여전히 완전한 반대 방향으로 돌아감 | 엉덩이가 덜 기운 만큼을 허리에 더함 (31번 항목) |
출처 및 유지 관리
- 출처: Cirra (AI 데스크 펫, RedCarpG/cirra-deskpet), 2026-10 ~ 2026-11.
- Live2D 코드:
src/pet/live2d.ts,src/pet/live2d-physics.ts,src/pet/cubism-core.ts; 렌더링 라이브러리untitled-pixi-live2d-engine1.4.0 (PixiJS 8). - VRM 코드:
src/pet/vrm.ts,src/pet/vrm-motion.ts, 2026-11-11부터vrm-face.ts,vrm-hands.ts,vrm-blend.ts,vrm-reach.ts,vrm-gaze.ts추가; 커밋 2b6ab57 (clampWhenFinished), e5e8687 (不使用 combineSkeletons). - 문서:
docs/stage5.md,docs/live2d-motions.md,docs/live2d-common-motions.md,docs/live2d-studio.md,docs/loop-motions.md,docs/expression-outfit-split.md,docs/music.md,docs/vrm.md,docs/vrm-motion.md,docs/vrm-motion-library.md,docs/vrm-studio.md,docs/vrm-toon.md,docs/beat-tracking.md,docs/vrm-skirt.md,docs/vrm-motion-polish.md. - 경험: 비공개 레포지토리의
lessons/live2d-motion.md,lessons/threejs-vrm-animation.md.
- Live2D 코드:
- 원본 저장소: RedCarpG/redcarpg-skills의
skills/live2d-vrm-animation/.~/.claude/skills/에 있는 것은 설치된 복사본이므로 직접 수정하지 마십시오. Cirra의 코드가 그 원천이며, 양쪽이 자동으로 동기화되지는 않습니다. - 수정 방법:
- redcarpg-skills에서 수정하고 PR을 보냅니다;
manifest.json버전을 올리고,node scripts/validate.mjs를 통과한 후 릴리스(taglive2d-vrm-animation-v<버전>)하고, 로컬 복사본을 다시 설치합니다. 먼저 위의 두 lessons 파일에 추가할 새 항목이 있는지 확인하십시오. - three.js, three-vrm, Live2D 렌더링 라이브러리가 업그레이드된 후, '가장 흔한 함정' 테이블에서 라이브러리 내부 동작과 관련된 항목들(mixer가 변하지 않은 값을 쓰지 않음,
clampWhenFinished,shouldRequestIdleMotion, 로딩 순서)을 재확인해야 합니다. - 하나의 모델에서만 관찰된 현상은 해당 모델 유형을 명시하고, 일반적인 규칙으로 작성하지 마십시오.
- redcarpg-skills에서 수정하고 PR을 보냅니다;
- 업데이트 기록:
- 2026-11-12 · 1.0.0, redcarpg-skills로 이전되어 공개 릴리스. 로컬 절대 경로를 수정하고, 출처 프로젝트를 링크로 변경; 내용은 동일.
- 2026-11-10 · Cirra · 초판: 세 가지 원칙, 함정 빠른 조회 테이블; Live2D, VRM, AI 생성 모션 세 가지 참조 문서;
evals/에 두 개의 테스트 프롬프트. - 2026-11-10 · Cirra · VRM 15번 항목(치마 관통) 수정: 기존에 '캡슐로 바꾸면 된다'고 썼지만 효과가 없어 충돌 그룹 등록, 범용 다리 캡슐, 엉덩이 점프 세 가지로 변경(
docs/vrm-skirt.md); 함정 빠른 조회 테이블에 한 줄 추가. - 2026-11-10 · Cirra · 15번 항목에 긴 머리가 소매 안으로 들어가는 경우(팔 캡슐을 안으로 줄일 수 없음), 옷이 튀어나오는 것은 스키닝 문제라고 추가.
- 2026-11-10 · Cirra · references/vrm.md에 'VRM 0.x의 정규화된 골격은 -Z 방향을 향함' 추가(프로그래매틱 포즈 방향 전환, 회전 시 rotateVRM0을 상쇄하지 않도록 함; 커밋 e2e6c0c,
src/pet/vrm-basis.ts). - 2026-11-11 · Cirra · references/vrm.md에 19–28번 항목(인터럽트 시 손 놓침 방지, 다리 포함 클립 페이드아웃 시 IK接管, 무릎 한계 및 발뒤꿈치 들기, 모션 캡처 손가락을 손 모양으로 교체, 손 모양과 손목, 손이 몸에 닿는 IK, 모션과 표정 조합, override가 beats를 막음, 빈 한쪽 눈 깜빡임, 눈과 머리 추종) 추가, 11번 항목을 25번 항목을 가리키도록 수정; ai-motion.md에 face, hands, reach의 형식과 검증 추가; 함정 빠른 조회 테이블에 9줄 추가. 출처:
docs/vrm-motion-polish.md§10, §11,src/pet/vrm-face.ts,vrm-hands.ts,vrm-blend.ts,vrm-reach.ts,vrm-gaze.ts,vrm-clip-extras.ts,vrm-pose.ts,sidecar/src/shared/motion-face.ts,motion-hands.ts(병합 커밋 b2f115d, ea3be9e). - 2026-11-11 · Cirra · references/vrm.md에 29–31번 항목(키프레임 구간 양쪽 끝이 느려서 끊김 → 단조로운 3차 스플라인 및 키프레임 오프셋; 기지개 켜기의 분할 및 상완 비틀기; 무릎 한계가 엉덩이 기울기를 줄여 상체가 기울어짐) 추가, 함정 빠른 조회 테이블에 3줄 추가. 출처:
docs/vrm-motion-polish.md§12,src/vrm-studio/motion-spec.ts의smoothAt,src/pet/vrm-pose.ts(병합 커밋 c5b4728). - 2026-11-11 · Cirra · references/live2d.md 21번 항목에 VTube Studio 모델의 두 가지 제외 사항 추가 (물리 입력, Param이 없는 얼굴 파라미터). 그렇지 않으면 얼굴 표정이 고개 끄덕임에 밀려남. 출처:
src/pet/clash.ts의standardInputs,isStandardParam,docs/expression-clash.md(커밋 7721742).