Вопрос или проблема
Я загрузил персонажа из mixamo и отдельно набор анимаций. Я настроил сцену с освещением, камерами, текстурированной землей и всем остальным. Я загружаю все анимации и затем воспроизводлю одну из них. Я настроил eventListener
, чтобы получить уведомление, когда анимация закончится (все это работает!). ТЕПЕРЬ я пытаюсь crossFadeTo
случайный endAction.
ЗДЕСЬ персонаж переходит в свою T-позу (это не то, что я хочу). Вот соответствующий код:
loadAnimations(){
const loader = new FBXLoader();
var that = this;
for(var i=0;i<this.animationFiles.length;i++){
loader.load(that.animationFiles[i],
function(animObj){
that.animations.push(animObj.animations[0]);
},
function(){
console.log(Math.round(100*((that.animations.length+1)/that.animationFiles.length))+'% загружено');
if((that.animations.length+1)==that.animationFiles.length) {
that.finishedLoading.bind(that)
that.finishedLoading();
}
}
);
}
}
finishedLoading(a){
console.log(this.animations)
this.tpose.animations = this.animations;
this.mixer = new THREE.AnimationMixer(this.tpose);
this.action = this.mixer.clipAction(this.tpose.animations[1]);
this.action.play();
this.mixer.addEventListener('loop',this.animationEnd.bind(this));
}
animationEnd(){
console.log('конец анимации');
var i= Math.floor(Math.random()*this.tpose.animations.length);
console.log('воспроизведение анимации#'+i);
const endAction = this.mixer.clipAction(this.tpose.animations[i]);
endAction.enabled = true;
endAction.setEffectiveTimeScale(1);
endAction.setEffectiveWeight(1);
endAction.time = 0;
endAction.weight=1;
this.action.crossFadeTo ( endAction, 1, true);
}
Я все endAction
части в animationEnd()
взял из различных примеров онлайн. В частности, я понимаю из этого, что особенно важно установить weight
на 1.
Ответ или решение
Для того чтобы правильно использовать метод crossFadeTo()
в библиотеке three.js и избежать проблемы перехода к позе T-Pose вместо выбора нужной анимации, вам следует обратить внимание на несколько ключевых моментов.
1. Убедитесь, что анимации загружаются корректно
Сначала убедитесь, что ваши анимации загружаются и добавляются к вашей модели без ошибок. В вашем методе loadAnimations()
проверьте, что каждая анимация добавляется в массив this.animations
. Стоит добавить логи для диагностики.
2. Обновление состояния анимаций
После завершения одной анимации и перед начала следующей, необходимо правильно сбрасывать состояние анимации. Убедитесь, что вы корректно обрабатываете анимации в методе animationEnd()
, где происходит переключение на новую анимацию.
3. Установка весов и времени анимации
Вот пример того, как можно доработать ваш метод animationEnd()
для предотвращения перехода к T-Pose:
animationEnd() {
console.log('анимация завершена');
var i = Math.floor(Math.random() * this.tpose.animations.length);
console.log('играем анимацию#' + i);
const endAction = this.mixer.clipAction(this.tpose.animations[i]);
// Убедитесь, что aннимация активна и вес не равен 0
endAction.enabled = true;
endAction.setEffectiveTimeScale(1);
endAction.setEffectiveWeight(1);
endAction.time = 0; // Сбрасываем время анимации
endAction.weight = 1; // Устанавливаем вес на 1
// Так как старое действие больше не обязательно, мы отключим его
// перед началом нового действия
this.action.crossFadeTo(endAction, 1, true);
// Меняем текущую анимацию на новую
this.action = endAction; // Назначаем новое действие текущим
}
4. Правильная асинхронная природа
Кроме того, убедитесь, что метод crossFadeTo()
вызывается после завершения предыдущего действия анимации. Это может быть причиной, по которой вы видите T-Pose, если анимация не обновляется правильно.
5. Проверка событий
Если метод loop
не срабатывает, можно рассмотреть альтернативные события, такие как finished
, чтобы удостовериться, что ваше действие завершено.
6. Инициализация mixer
и tpose
Убедитесь, что ваш mixer
и tpose
корректно инициализируются перед тем, как вы попытаетесь использовать их для анимации. Обязательно обеспечьте, чтобы модель загружалась и добавлялась в сцену до того, как вы начнете работать с анимациями.
Заключение
Сделав указанные выше шаги, проблема с переходом к T-Pose должна решиться. Не забывайте использовать console.log
для отладки и понимания, какие анимации загружаются и как они проигрываются. Это поможет вам лучше контролировать процесс и избегать непредвиденных ситуаций.