Работа с анимациями 3D-объектов
В отличие от простого редактора, в продвинутом можно более расширенно работать с анимациями. Можно как запускать несколько подряд, так и просто анимировать через определенный промежуток времени.
Добавление 3D-объекта и его проверка
Для работы с анимациями, первым делом нужно добавить 3D-объект на сцену и проверить его на наличие анимаций.

У объектов с анимацией появится дополнительный блок справа.

Здесь, в выпадающем списке, вы можете увидеть, сколько дорожек имеет модель. А так же, по нажатию по кнопку PLAY, проиграть выбранную анимацию.

Таким образом, если все нужные анимации работаю исправно, можно приступать к работе с ними.
Запуск анимации
Для того чтобы 3D-объект воспроизводил анимацию при запуске сцены, нужно создать сценарий.
О том, как создавать сценарии читайте Создание сценариев для сцены.
Запуск одной анимации
Далее, внутри редактора кода созданного сценария, нужно написать несколько строк кода.

Первым делом нужно создать новую переменную, внутри которой будет находиться анимационный клип, который будет запускаться (строка 1).
const clip = this.animations[0];
Давайте разберем этот код: this
— это обращение к этой 3D-модели (в случае, если скрипт привязан к 3D-объекту), animations
— массив все анимационных клипов объекта, [0]
— порядковый номер клипа (отсчет всегда начинается с 0, так как это массив, а последний клип будет иметь число n-1).
Так как в данном случае у модели целых два клипа, нужно создать переменные сразу для них обоих (строка 1-2).
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
Теперь нужно создать AnimationMixer
. AnimationMixer
— это проигрыватель для анимации объекта на сцене (строка 3).
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
В качестве параметра метода нужно передавать 3D-объект, который нужно анимировать.
Следующим шагом нужно создать переменную, в которую будет записан метод миксера (AnimationMixer
) .clipAction
. Данный метод возвращает AnimationAction
.
Так как у данной модели два анимационных клипа, нужно создать две переменные, которые будут возвращать AnimationAction
(строки 4-5).
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
Дальше, нужно сделать так, чтобы AnimationMixer
обновлялся каждый кадр. Если этого не сделать, анимация просто не будет запущена или будет работать неверным образом. Для этого, нужно создать новую переменную, в которой будет помещен объект THREE.Clock
. Он нужен для отслеживания времени (строка 1).
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
После этого, нужно создать функцию update()
. Эта функция, которая вызывается каждый кадр (строки 8-10).
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
function update() {
}
Внутри этой функции нужно создать условный оператор if
, который, проверяя присутствие миксера, будет обновлять анимацию каждый кадр. Это будет выглядеть следующим образом (строки 9-11).
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
function update() {
if (mixer) {
mixer.update(clock.getDelta());
}
}
Все, теперь все готово к запуску анимации. С помощью AnimationAction
, можно запустить любой клип, к примеру первый (строка 7).
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
actionforClipOne.play();
function update() {
if (mixer) {
mixer.update(clock.getDelta());
}
}
Запуск нескольких (двух) анимаций подряд
Теперь, после того, как мы научились запускать одну анимацию, можно перейти к запуску несколько анимаций подряд. Для этого, мы будем пользоваться встроенными в THREE.js часами THREE.Clock
и функцией update()
.
Код запуска первой анимации, сделанный выше:
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
actionforClipOne.play();
function update() {
if (mixer) {
mixer.update(clock.getDelta());
}
}
Далее, нужно создать еще один условный оператор if
внутри функции update()
, который будет проверять прошло ли с начала старта сцены время, равное длительности первой анимационной дорожки (clipOne
). Внутри оператора будет сравниваться количество секунд (clipOne.duration
) первого клипа с текущим временем (clock.elapsedTime()
).
Это нужно для того, чтобы остановить воспроизведение анимации первого клипа и сразу же воспроизвести анимацию второго клипа (строка 13-15).
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
actionforClipOne.play();
function update() {
if (mixer) {
mixer.update(clock.getDelta());
}
if (clipOne.duration < clock.getElapsedTime()) {
}
}
Теперь нужно добавить код, который будет выполняться внутри условия. Этот кусок кода должен останавливать воспроизведение первого клипа и запускать второй клип (строка 14).
const clock = new THREE.Clock();
const clipOne = this.animations[0];
const clipTwo = this.animations[1];
const mixer = new THREE.AnimationMixer(this);
const actionforClipOne = mixer.clipAction(clipOne);
const actionforClipTwo = mixer.clipAction(clipTwo);
actionforClipOne.play();
function update() {
if (mixer) {
mixer.update(clock.getDelta());
}
if (clipOne.duration < clock.getElapsedTime()) {
actionforClipOne.stop();
actionforClipTwo.play();
}
}
Таким образом, после окончания проигрывания первой анимации модели, сразу же начнется вторая.
Last updated