A-Frame поддерживает анимации, встроенные в форматы 3D-моделей, включая glTF и GLB. Эти форматы позволяют хранить скелетные анимации (skeletal/bone animations) и анимированные трансформации объектов (node animations). Важное отличие заключается в том, что скелетные анимации управляют костями модели, а node-анимации изменяют позицию, вращение и масштаб конкретных узлов сцены.
Для работы с анимациями glTF используется компонент
gltf-model и дополнительный компонент
animation-mixer, который интегрирован в A-Frame и работает
на основе Three.js. Он автоматически считывает доступные анимации из
модели и предоставляет возможность их управления.
<a-entity gltf-model="#robotModel" animation-mixer></a-entity>
В этом примере animation-mixer подключается к модели
робота. По умолчанию воспроизводится первая анимация из файла glTF.
Компонент animation-mixer позволяет гибко управлять
анимациями:
clip позволяет указать имя или индекс анимации:<a-entity gltf-model="#robotModel"
animation-mixer="clip: Walk"></a-entity>
loop управляет цикличностью:<a-entity gltf-model="#robotModel"
animation-mixer="clip: Run; loop: repeat"></a-entity>
Допустимые значения: repeat (циклично),
once (один раз), pingpong (обратное
воспроизведение).
timeScale изменяет скорость анимации:<a-entity gltf-model="#robotModel"
animation-mixer="clip: Walk; timeScale: 2"></a-entity>
Значение 2 ускоряет анимацию в два раза.
Для динамического контроля анимаций используется стандартный подход
Three.js через animation-mixer:
const entity = document.querySelector('#robot');
const mixer = entity.components['animation-mixer'].mixer;
const clips = entity.getObject3D('mesh').animations;
// Воспроизведение конкретной анимации
const action = mixer.clipAction(clips.find(clip => clip.name === 'Jump'));
action.reset().play();
// Плавное смешивание (crossfade) между анимациями
const runAction = mixer.clipAction(clips.find(clip => clip.name === 'Run'));
action.crossFadeTo(runAction, 0.5, true);
Метод crossFadeTo позволяет делать плавные переходы
между анимациями, что особенно важно для реалистичных движений
персонажей.
A-Frame и Three.js поддерживают анимационные слои, что позволяет одновременно проигрывать несколько анимаций:
const walkAction = mixer.clipAction(clips.find(c => c.name === 'Walk'));
const waveAction = mixer.clipAction(clips.find(c => c.name === 'Wave'));
walkAction.play();
waveAction.play();
waveAction.setEffectiveWeight(0.5); // Полупрозрачное смешивание
Использование setEffectiveWeight позволяет задавать
относительное влияние анимации, что удобно для комбинирования базовой
походки с жестами рук или головы.
Компонент animation-mixer может реагировать на события,
передаваемые Three.js:
entity.addEventListener('animation-finished', (event) => {
console.log('Анимация завершена:', event.detail.action._clip.name);
});
Эта функциональность особенно полезна для игровых механик, когда необходимо выполнять действия после завершения определенной анимации.
Для корректной работы анимаций в A-Frame модель должна:
Программы типа Blender или Maya позволяют экспортировать анимации прямо в glTF, сохраняя все ключевые кадры и скелетные структуры.
A-Frame позволяет комбинировать animation-mixer с
собственным компонентом animation, создавая эффекты
перемещения или вращения всей модели:
<a-entity gltf-model="#robotModel"
animation-mixer="clip: Walk"
animation="property: position; to: 0 0 -5; dur: 3000; loop: true"></a-entity>
Такой подход позволяет одновременно управлять анимацией скелета и глобальной трансформацией объекта, создавая комплексные динамические сцены.