Как заставить работать crossFadeTo() в three.js

Вопрос или проблема

Я загрузил персонажа из 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 для отладки и понимания, какие анимации загружаются и как они проигрываются. Это поможет вам лучше контролировать процесс и избегать непредвиденных ситуаций.

Оцените материал
Добавить комментарий

Капча загружается...