LoginSignup
0
1

More than 3 years have passed since last update.

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

Posted at

困った

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

いい感じになった

立方体の6面とも異なる画像を表示できるコンポーネントを調べてみると、良さそうなのがありました。
aframe-multisrc-component
dice.gif
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);
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1