困った

A-Frameでサイコロを作りたいのですが、標準のマテリアルコンポーネントだと立方体の6面とも同じ画像が表示されてしまいます。

demo
これでは困る。

いい感じになった

立方体の6面とも異なる画像を表示できるコンポーネントを調べてみると、良さそうなのがありました。
aframe-multisrc-component

demo
いい感じになりました。
個々の面に対して色を指定したり、メタリックにしたりもできるようです。

バグっぽい

使ってみて気づいたのですが、

  • multisrcコンポーネントをエンティティから削除する
  • multisrcコンポーネントを持つエンティティを削除する

のどちらかを実行すると、multisrcコンポーネントのremoveイベントが発火しますが、その中の処理にバグがあるっぽいです。

以下のようなエラーが発生します。

Cannot read property 'addEventListener' of undefined

ループの中からthisが参照できなくなっているようです。

remove: function(){
    var defaultMaterial = this.el.components.material.material 
    this.el.getObject3D('mesh').material = defaultMaterial
    this.el.removeEventListener('componentchanged', this.compChange);
    var animationEventsArray = ['animationbegin', 'animationstart', 'animationcomplete', 'animationend']
    animationEventsArray.forEach(function(event) {
      this.el.addEventListener(event, this.materialChangedByAnimation) // <- ここでthisがundefinedになる
    });
    this.reduceMaterialChangedThrottle(200);
}

このコードを追記してremove関数を上書きしてあげると、とりあえずうごきました。

AFRAME.components.multisrc.Component.prototype.remove = function () {
    var defaultMaterial = this.el.components.material.material;
    this.el.getObject3D('mesh').material = defaultMaterial;
    this.el.removeEventListener('componentchanged', this.compChange);
    var animationEventsArray = ['animationbegin', 'animationstart', 'animationcomplete', 'animationend'];
    var self = this; // <- thisをselfで保持してループの中からも参照できるようにした
    animationEventsArray.forEach(function (event) {
        self.el.addEventListener(event, self.materialChangedByAnimation); <- thisをselfに置き換えた
    });
    this.reduceMaterialChangedThrottle(200);
}

元記事はこちら

A-Frame: aframe-multisrc-componentの調査