Изменение положения объекта Collade с течением времени в ThreeJS - PullRequest
0 голосов
/ 22 января 2019

Я использую пример эльфа, который является стандартным примером с ThreeJS

Вместо поворота, показанного в примере, я хочу переместить объект как в направлении x, так и в направлении y. Это должно быть достигнуто путем изменения elf.position.x и elf.position.y в функции init ().

Эта проблема, с которой я сталкиваюсь, заключается в том, что я создал объект (класс) методов, которые создают эльфа, поэтому я могу создать несколько из них. У меня также есть функция, которая должна перемещать объект с течением времени. var e недоступно в функции перемещения. Когда я изменяю его на this.e и меняю e = collada.scene; на this.e = collada.scene;, я получаю следующую ошибку: Uncaught TypeError: Cannot set property 'e' of undefined

Код:

 class DrawElf {
    constructor(scene) {
        var e;
        this.loadingManager = {};
        this.loader = {};
        this.scene = scene;

        // loading manager
        this.loadingManager = new THREE.LoadingManager(function () {
            scene.add(e);
        });

        // collada
        this.loader = new THREE.ColladaLoader(this.loadingManager);
        this.loader.load('./models/collada/elf/elf.dae', function (collada) {
            e = collada.scene;
            e.scale.set(30, 30, 30);
            e.position.set(100, 10, 100);
            e.name = "elf.dae" + 0 + 0;

            e.traverse(function (child) {
                if (child instanceof THREE.Mesh) {
                    child.name = e.name;
                    ToIntersect.push(child);
                }
            });
        });
    }

    move(time) {
        // i want to move the object
    }
}

Надеюсь, кто-нибудь может помочь.

1 Ответ

0 голосов
/ 22 января 2019

Я отредактировал ваш пример кода, чтобы показать, как получить доступ к модели эльфов в функции move(), и вызвал изменения в комментариях ниже.

class DrawElf {
    constructor(scene) {

        // Change 1: Place the `e` variable on `this` so it's accessible
        // from member functions like `move`
        this.e = null;
        this.loadingManager = {};
        this.loader = {};
        this.scene = scene;

        // Change 2: Use arrow functions instead so that the scope of the
        // constructor is retained in the callback and `this` still references
        // the new `DrawElf` instance 
        // collada
        this.loader = new THREE.ColladaLoader();
        this.loader.load('./models/collada/elf/elf.dae', (collada) => {
            this.e = collada.scene;
            this.e.scale.set(30, 30, 30);
            this.e.position.set(100, 10, 100);
            this.e.name = "elf.dae" + 0 + 0;

            this.e.traverse(function (child) {
                if (child instanceof THREE.Mesh) {
                    child.name = this.e.name;
                    ToIntersect.push(child);
                }
            });


            // Change 3: Remove the loading manager because it's not needed to
            // add the elf to the scene and instead do so here
            scene.add(this.e);
        });
    }

    move(time) {
        // Change 4: Check if the scene has been loaded before trying to move
        // the model
        if (this.e) {
            // move the model here
        }
    }
}

Большим изменением здесь является использование функций стрелки вместо оригинальных функций Javascript, поэтому this по-прежнему ссылается на конструируемый экземпляр объекта. Этот SO-ответ должен объяснить немного больше различий в области видимости.

Надеюсь, это поможет! Дайте мне знать, если что-то неясно.

...