вызов дочерних объектов object3D для уникальных стилей / анимаций - PullRequest
1 голос
/ 07 мая 2020

Мне интересно, как бы я go мог вызывать отдельных дочерних элементов куба (mesh0, mesh1), чтобы я мог установить разные стили / анимации для них обоих.

AFRAME.registerComponent('multi_box', {
  schema: {},
  update: function() {
  for (var i = 0; i < 2; i++) {
    var material = new THREE.MeshBasicMaterial({color: "blue"});
    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var cube = new THREE.Mesh(geometry, material);
    cube.position.x = i == 0 ? -1 : 1;
    cube.position.y = 0.5;
    cube.position.z = -5;

    this.el.setObject3D("mesh"+i, cube); //unique name for each object
}
    console.log(this.el.object3DMap)  
}
});

Ссылка Codepen: https://codepen.io/ubermario/pen/wrwjVG

Я могу console.log их обоих и увидеть, что они являются уникальными объектами друг для друга, но у меня проблемы вызывая их:

var meshtest = this.el.getObject3D('mesh0')
console.log(meshtest.position)

Я пробовал этот метод, но безуспешно: aframe get object3d children

Любая помощь приветствуется :)

1 Ответ

3 голосов
/ 07 мая 2020

Создание экземпляра

В вашем цикле for вы создаете

  1. новый экземпляр геометрии
  2. новый экземпляр материала
  3. новый me sh, которые соединяют два предыдущих

Каждое ключевое слово new создает уникальный экземпляр, независимый от других. В вашем случае mesh0 и mesh1 полностью независимы друг от друга. Если вы измените какое-либо свойство экземпляра, например, цвет или положение материала, это не повлияет на другие свойства. Фактически, вы делаете это, присваивая каждому кубу разные позиции x .

Хранение

Ваш компонент содержит карту трехмерных объектов. Каждый идентифицируется уникальным именем. Это имя создается путем объединения префикса me sh с номером итерации (значение i).

Позже вы сможете получить доступ к кубам точно так же, как вы их создали. Либо по имени

this.el.getObject3D('mesh0')
this.el.getObject3D('mesh1')
//etc.

, либо по индексу

this.el.object3D.children[0]
this.el.object3D.children[1]

, и вы можете управлять ими дальше. Например, вы можете поместить его в Ln19 в своем коде:

this.el.getObject3D('mesh0').position.y = 2;
this.el.object3D.children[1].position.z = -3;

Просто для полноты: Если вы опустите +i в конце, вы снова перезапишите тот же ключ и снова, поэтому me sh будет ссылаться только на последний куб, а другие будут потеряны.

Изменение свойств

3. js имеет приятный API, но в javascript всегда нужно думать о том, что происходит за кадром. Вы увидите это, изучая новый материал. Например:

this.el.object3D.children[1].position.z = -3;
this.el.object3D.children[1].material.color.set('#ffff00');
this.el.object3D.children[1].material.color = [1, 1, 0];

Как видите, положение можно изменить напрямую, но иногда цвет требует установки. С векторами все усложняется, когда вам нужно наблюдать, какие методы изменяют текущий экземпляр, а какие создают новый. Вы можете легко забыть clone это. Скажем, у вас было:

var pos = new THREE.Vector3(-1, 0.5, -5)
for (var i = 0; i < 2; i++) {
    var material = new THREE.MeshBasicMaterial({color: "blue"});
    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var cube = new THREE.Mesh(geometry, material);

    //wrong, since it will assign the object reference,
    //i.e. always the same object.
    //Thus, the cubes will be at one position in the end
    cube.position = pos;

    //right
    cube.pos = pos.clone();

    pos.x += 1;
    this.el.setObject3D("mesh"+i, cube); //unique name for each object
}

Разница немного более умеренная, c для ссылочных и значений типов. Вы найдете множество руководств по этому поводу, например это небольшое содержание Я только что нашел.

Надеюсь, это было полезно и sh у вас хороший прогресс в обучении!

...