Animação de Personagens Live2D / VRM
Este skill vem de um desk pet que suporta personagens Live2D e VRM (veja "Fonte e Manutenção" no final). Os modelos utilizados incluem exemplos oficiais, modelos do VTube Studio e VRMs convertidos do VRChat. Todas as práticas descritas abaixo foram testadas, medidas ou revisadas por usuários.
Três Princípios que Atravessam Ambos os Tipos de Personagens
- A camada procedural e os clipes de animação se sobrescrevem mutuamente. Quem é calculado primeiro a cada frame e quem escreve por último determina o que o usuário vê. Quase todos os problemas de "piscar", "mão que cai" e "cabeça que não mexe" vêm daqui:
- Live2D: Os valores sobrepostos pelo código procedural devem ficar dentro de
beforeModelUpdate— senão não entram na física, e cabelo/corpo não acompanham. A solução é envolverphysics.evaluatee sobrepor antes da física. - VRM: O
AnimationMixerdo three.js, quando os valores misturados em um frame são iguais aos do frame anterior, não escreve nos ossos. A pose estática programada (postura, respiração) a cada frame vai vazar através das partes "paradas" do clipe. É preciso pular os ossos que estão sendo escritos pelo clipe em execução (usando os nomes dos nós emclip.tracks). Ao pausar, também é necessário parar a reescrita procedural da postura.
- Live2D: Os valores sobrepostos pelo código procedural devem ficar dentro de
- Não modifique os arquivos de animação; adicione uma camada procedural depois. Animações feitas à mão (keyframes) ou geradas por IA geralmente movem apenas alguns ossos (acenar só mexe o braço), parecendo fantoches. Adicione uma camada procedural após o clipe que calcula "arrastamento" (ombro que sobe junto, tronco que cede, pulso que atrasa, cabeça que segue meio tempo) — sem sobrepor ossos que o clipe já escreve. Feito uma vez, beneficia todas as animações e pode ser ligado/desligado para comparação.
- Validação por contagem quadro a quadro, não a olho. Problemas de animação duram apenas um ou dois quadros; é quase impossível confirmar visualmente se foram corrigidos. Registre quadro a quadro o valor do osso (parâmetro) no momento em que é desenhado (após o render, ou lendo em
beforeModelUpdatedo Live2D), compare antes e depois da correção; depois faça capturas de tela em dois modelos diferentes.
Quando Ler Onde
| O que fazer | Leia |
|---|---|
| Live2D: carregamento, escrita de parâmetros, física, idle, ações, travar, expressões | references/live2d.md |
| VRM: pose procedural e clipes, camada de arrastamento, clipes de captura de movimento, expressões, SpringBone, janela transparente | references/vrm.md |
| VRM: ação com expressão, formas de mão e pulso, mão tocando o corpo (IK), interrupção sem soltar a mão, limites de perna, olho que segue a cabeça, interpolação de keyframes e segmentação | references/vrm.md itens 19–31 |
| Gerar ou modificar expressões/ações com IA | references/ai-motion.md |
| Balançar a cabeça no ritmo da música, movimento de cabeça ao falar | references/live2d.md item 16, references/vrm.md "Seguir o ritmo" |
Armadilhas Mais Comuns (Consulte Primeiro Estas)
| Fenômeno | Causa | Solução |
|---|---|---|
| Live2D reporta "Could not find Cubism runtime" ou não desenha | Ordem de carregamento errada | Cubism Core → módulo que registra o render pipe → PixiJS Application.init() → modelo |
| Live2D escreve parâmetros e lê valores estranhos como 58, null | Passou string ID diretamente | Use internalModel.getIdSafe(name) para obter o handle |
| Live2D cabeça não acompanha (modelo VTube Studio) | ParamAngle* é saída da física, é sobrescrito | Leia physics3.json, escreva no parâmetro de entrada correspondente |
| Live2D só a cabeça balança, cabelo/corpo não | Sobreposição colocada depois da física | Envolva physics.evaluate, sobreponha antes dela |
| Live2D parado, sem movimento | Modelo VTube Studio não tem um Idle decente | Idle procedural: três senoides lentas na cabeça/corpo + respiração, escreva só parâmetros padrão |
Live2D stopAllMotions seguido de movimento espontâneo | Engine percebe que não há ação e reproduz Idle novamente | Aponte motionManager.groups.idle para um grupo inexistente, depois pare breath |
| VRM mão cai durante pausa de keyframe; pisca no início/fim | Mixer não escreve valores inalterados, pose procedural vaza | Pose procedural pula ossos que o clipe está escrevendo |
| VRM ação de uso único volta em um frame ao final | clampWhenFinished=false faz o mixer fechar a ação antes de finished | clampWhenFinished = true, depois fadeOut |
| VRM captura de movimento fica com postura muito larga, desloca no início, saia voando | Clipe tem quadris e pernas próprios | Ao converter, remova trilhas de quadris e pernas, use apenas tronco superior |
| VRM saia atravessa a coxa, linhas auxiliares de colisão mostram só uma ou duas esferas | Colididores não registrados no grupo de colisão da cadeia de molas (three-vrm só reconhece os registrados) | Adicione cápsulas de perna na cadeia abaixo do quadril usando ossos padrão; não pule o quadril em um frame (references/vrm.md item 15) |
| VRM expressões do clipe não aparecem | Expressões de estado (piscar, boca) sobrescrevem a cada frame | Clipe escreve só ossos |
| Expressão não visível em tamanho pequeno | Arquivo de expressão só modifica uma área pequena | Sobreponha mais parâmetros (apertar olhos, rubor, inclinar cabeça, canto da boca) |
| VRM rosto sem expressão durante ação | Expressão só segue estado, ação não carrega | Junto à ação, escreva mood + beats, misture pelo peso da ação (references/vrm.md item 25) |
| Ação quer fechar olhos/abrir boca, mas expressão "cansado"/"sorriso" do modelo bloqueia | overrideBlink/overrideMouth da expressão é block | Naquele momento, suprima essas expressões (item 26) |
| VRM piscar de um olho não aparece | blinkLeft/blinkRight não vinculados a morph targets | Pisque os dois olhos juntos, semi-fechando (item 27) |
| VRM uma ação interrompe outra; mão cai e sobe de novo | Nova ação começa da pose estática, crossfade passa pela pose | Comece do frame mais parecido da nova ação com a pose atual + transição a partir do momento da interrupção (item 19) |
| VRM dedos de captura de movimento retos ou punho fechado; keyframe de mão sempre semi-aberta | Redirecionamento dos dedos / ação não escreve dedos | Remova dedos da captura, escreva forma de mão na ação (itens 22, 23) |
| Apoiar queixo, cobrir boca, coração — com outro corpo não acerta o lugar | Só ângulos escritos | Calcule alvo por ossos e malha em tempo real, IK de dois segmentos (item 24) |
| Fim de dança: pé volta em um frame | IK da perna assume no mesmo frame que o fade-out começa | IK assume gradualmente conforme peso da ação com perna (item 20) |
| Joelho semi-flexionado, perna relaxada dobra demais | Várias camadas de deslocamento do quadril se acumulam | Limite superior do joelho, reduza deslocamento do quadril pela metade; levantar calcanhar aumenta a dobra (item 21) |
| VRM olhos fixos na câmera o tempo todo | lookAt aponta para a câmera; ao virar a cabeça, olhos viram ao contrário | Ao virar a cabeça, olhos seguem a cabeça, pisque ao virar, micro-movimentos oculares (item 28) |
| Keyframe de mão trêmulo, não suave | Cada segmento de keyframe tem extremidades lentas, cada keyframe com velocidade 0 | Spline cúbica monotônica + keyframes defasados entre segmentos (item 29) |
| Espreguiçar, levantar braço: braço sobe reto dos lados / estica para os lados | Faltam segmentos de punho fechado e antebraço dobrado; torção e elevação não separadas | Refazer em segmentos, torção só no momento da porta (item 30) |
| Trocar peso em repouso: tronco inteiro inclina para um lado | Limite do joelho reduziu a inclinação do quadril, mas cintura e peito ainda giram completos | Adicione ao tronco a parte que o quadril deixou de inclinar (item 31) |
Fonte e Manutenção
- Fonte: Cirra (desk pet com IA, RedCarpG/cirra-deskpet), outubro a novembro de 2026.
- Código Live2D:
src/pet/live2d.ts,src/pet/live2d-physics.ts,src/pet/cubism-core.ts; biblioteca de renderizaçãountitled-pixi-live2d-engine1.4.0 (PixiJS 8). - Código VRM:
src/pet/vrm.ts,src/pet/vrm-motion.ts, a partir de 2026-11-11 tambémvrm-face.ts,vrm-hands.ts,vrm-blend.ts,vrm-reach.ts,vrm-gaze.ts; commits 2b6ab57 (clampWhenFinished), e5e8687 (não usar combineSkeletons). - Documentação:
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. - Experiência: repositório privado
lessons/live2d-motion.md,lessons/threejs-vrm-animation.md.
- Código Live2D:
- Origem: RedCarpG/redcarpg-skills em
skills/live2d-vrm-animation/. O que está em~/.claude/skills/é uma cópia instalada; não modifique diretamente. O código do Cirra é a fonte; os dois lados não sincronizam automaticamente. - Como modificar:
- Altere no redcarpg-skills, via PR; incremente a versão no
manifest.json, executenode scripts/validate.mjse, se passar, publique (taglive2d-vrm-animation-v<versão>), depois reinstale a cópia local. Primeiro verifique se os dois arquivos de lessons acima têm novos itens para incorporar. - Após atualizações do three.js, three-vrm ou da biblioteca de renderização Live2D, reconfirme os itens da tabela "Armadilhas Mais Comuns" que dependem do comportamento interno (mixer não escreve valores inalterados,
clampWhenFinished,shouldRequestIdleMotion, ordem de carregamento). - Fenômenos observados em apenas um modelo devem ser identificados com o tipo de modelo; não generalize.
- Altere no redcarpg-skills, via PR; incremente a versão no
- Histórico de versões:
- 2026-11-12 · 1.0.0, movido para redcarpg-skills e publicado abertamente. Caminhos absolutos locais alterados, projeto fonte referenciado como link; conteúdo inalterado.
- 2026-11-10 · Cirra · Primeira versão: três princípios, tabela rápida de armadilhas; três referências: Live2D, VRM, geração de movimentos por IA; dois prompts de teste em
evals/. - 2026-11-10 · Cirra · Alterado item 15 do VRM (saia atravessando): o que estava escrito ("mude para cápsula e resolve") não funcionou; substituído por três itens (registro no grupo de colisão, cápsula universal de perna, salto do quadril) (
docs/vrm-skirt.md); adicionada uma linha na tabela de armadilhas. - 2026-11-10 · Cirra · Item 15 adiciona: cabelo comprido entrando na manga (cápsula do braço não pode recuar), roupa estufada é problema de skinning.
- 2026-11-10 · Cirra ·
references/vrm.mdadicionado: "Esqueletos padronizados VRM 0.x virados para -Z" (pose procedural muda orientação, não desfazer rotateVRM0; commit e2e6c0c,src/pet/vrm-basis.ts). - 2026-11-11 · Cirra ·
references/vrm.mdadicionados itens 19–28 (interrupção sem soltar mão, fade-out de clipe com perna com IK assumindo, limite do joelho e levantar calcanhar, dedos de captura substituídos por forma de mão, forma de mão e pulso, mão tocando corpo com IK, ação com expressão, override bloqueando beats, piscar de um olho vazio, olho que segue a cabeça), item 11 alterado para apontar para item 25;ai-motion.mdadicionados formatos e validação para face, hands, reach; tabela de armadilhas ganha 9 linhas. Fonte: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(merge commits b2f115d, ea3be9e). - 2026-11-11 · Cirra ·
references/vrm.mdadicionados itens 29–31 (keyframes com extremidades lentas causando tremor → spline cúbica monotônica e keyframes defasados; segmentação de espreguiçar e torção do braço; limite do joelho reduz inclinação do quadril resultando em tronco inclinado), tabela de armadilhas ganha 3 linhas. Fonte:docs/vrm-motion-polish.md§12,smoothAtemsrc/vrm-studio/motion-spec.ts,src/pet/vrm-pose.ts(merge commit c5b4728). - 2026-11-11 · Cirra ·
references/live2d.mditem 21 adiciona duas categorias de exclusão para modelos VTube Studio (entrada física, parâmetros faciais sem Param), senão expressão facial cede ao balançar a cabeça. Fonte:standardInputseisStandardParamemsrc/pet/clash.ts,docs/expression-clash.md(commit 7721742).