处理AFrame中的GearVR控制器事件

时间:2018-01-11 01:38:26

标签: aframe

所以,我应该首先警告我是AFrame的新手,(虽然不是编程,游戏编程或Javascript)。我目前正试图将一个简单的场景与基本的GearVR控制器交互结合在一起。

当我说"基本互动"时,我的意思是当你按照official tutorial时我得到了一个小小的启动场景,而我只是试图扩展它,这样当你按下触发器(特别是触发器,而不仅仅是任何按钮)时,小文本组件的文本值就会改变。

长话短说 - 我的代码没有用。尽管事实上我在组件init函数中添加了事件监听器(并且我已经确认正在调用init),但似乎从未调用过监听器回调。如果我不得不猜测,我会说我已经附加的实体激光控制'并没有发出'触发器'事件,但我不知道如何确认。以下是相关部分:



AFRAME.registerComponent('gearvr-trigger', {
  schema: {
    textValue: {
      default: "Hello WebVR!"
    }
  },

  init: function() {
    var message_box = document.querySelector('#message');
    var el = this.el;

    el.addEventListener('triggerdown', function(evt) {
      message_box.setAttribute('value', this.data.textValue);
    });

  }


});

  <a-text id='message' value="Hello, A-Frame!" color="#BBB"
    position="-0.9 0.2 -3" scale="1.5 1.5 1.5">
  </a-text>


<a-box gearvr-trigger='textValue: "New Text Value";' src='#boxTexture' position='0 2 -5' rotation='0 45 45' scale='2 2 2'>
  <a-animation attribute='position' to='0 2.5 -5' direction='alternate' dur='2000' repeat='indefinite'></a-animation>
  <a-animation attribute="scale" begin="mouseenter" dur="300" to="2.3 2.3 2.3"></a-animation>
  <a-animation attribute="scale" begin="mouseleave" dur="300" to="2 2 2"></a-animation>
  <a-animation attribute="rotation" begin="click" dur="2000" to="360 405 45"></a-animation>
</a-box>
<a-entity raycaster='far: 100; showLine: true;' line='color: red;' laser-controls></a-entity>
&#13;
&#13;
&#13;

如果有比我更多经验的人看到我做错了什么,那就太好了,但是如果你能指出一些代表我回应GearVR控制器的代码示例,我也很高兴事件

4 个答案:

答案 0 :(得分:0)

尝试setAttribute('text','value,'无论你想要什么')?

答案 1 :(得分:0)

如果它不是触发代码,则可能是范围问题: &#39;这&#39;是指处理程序中的元素而不是组件,因此在事件

期间未定义this.data

潜在的解决方法:

AFRAME.registerComponent('gearvr-trigger', {
  schema: {
    textValue: {
      default: "Hello WebVR!"
    }
  },

  init: function() {
    var message_box = document.querySelector('#message');
    var el = this.el;

    var self = this;
    el.addEventListener('triggerdown', function(evt) {
      message_box.setAttribute('value', self.data.textValue);
    });
  }
});

或使用箭头功能

AFRAME.registerComponent('gearvr-trigger', {
  schema: {
    textValue: {
      default: "Hello WebVR!"
    }
  },

  init: function() {
    var message_box = document.querySelector('#message');
    var el = this.el;

    el.addEventListener('triggerdown', (evt) => {
      message_box.setAttribute('value', this.data.textValue);
    });
  }
});

答案 2 :(得分:0)

triggerdown事件在具有激光控制属性的实体上触发。

我的代码使用click事件并响应任一按钮(与您想要的不同),但实现此模式可能会推动您前进。 (它还涉及跨设备操作的路径。)click事件可能包含按下了哪个按钮。

在场景中,我有:

<a-entity laser-controls="hand: right"></a-entity>

在脚本中,我注册

    AFRAME.registerComponent('cursor-listener', {
        init: function () {
            var lastIndex = -1;
            var COLORS = ['purple', 'orange', 'white'];
            this.el.addEventListener('click', function (evt) {
                lastIndex = (lastIndex + 1) % COLORS.length;
                this.setAttribute('material', 'color', COLORS[lastIndex]);
                console.log('I was clicked at: ', evt.detail.intersection.point);
            });
        }
    });

然后我在目标框上设置cursor-listener属性:

boxEl.setAttribute('cursor-listener', true);

答案 3 :(得分:0)

正如其他人所说,你没有在自定义组件中获取'triggerdown'事件的原因是这些事件是由控制器实体(在这种情况下为a-entity[laser-controls])发出的,并且它们是泡泡就像在标准DOM中一样(在这种情况下它会在a-scene旁边),所以a-box没有看到它们。

当您将控制器按钮的信息和控制器与场景中其他实体的关系(例如,用激光或碰撞指向)组合在一起时,我喜欢称之为手势。 laser-controls组件提供了基本的手势解释,但我创建了super-hands package for rich gesture interpretation,包括您需要的内容:按钮歧视。

<html>
<head>
<script src="https://aframe.io/releases/0.7.1/aframe.min.js"></script>
<script src="https://unpkg.com/super-hands/dist/super-hands.min.js"></script>
<script>
AFRAME.registerComponent('gearvr-trigger', {
  schema: {
    textValue: {
      default: "Hello WebVR!"
    }
  },

  init: function() {
    var message_box = document.querySelector('#message');
    var el = this.el;
    var triggerResponse = function (evt) {
      if (evt.detail.state === 'clicked') {
        message_box.setAttribute('value', this.data.textValue);
      }
    }
    el.addEventListener('stateadded', triggerResponse.bind(this));

  }

});
</script>
</head>
<body>
<a-scene>
<a-assets>
  <a-mixin id="point-laser" raycaster='far: 100; showLine: true;' line='color: red;'></a-mixin>
</a-assets>
<a-text id='message' value="Hello, A-Frame!" color="#BBB"
    position="-0.9 0.2 -3" scale="1.5 1.5 1.5">
  </a-text>


<a-box clickable="startButtons: triggerdown, mousedown; endButtons: triggerup, mouseup" gearvr-trigger='textValue: "New Text Value";' src='#boxTexture' position='0 2 -5' rotation='0 45 45' scale='2 2 2'>
  <a-animation attribute='position' to='0 2.5 -5' direction='alternate' dur='2000' repeat='indefinite'></a-animation>
  <a-animation attribute="scale" begin="hover-start" dur="300" to="2.3 2.3 2.3"></a-animation>
  <a-animation attribute="scale" begin="hover-end" dur="300" to="2 2 2"></a-animation>
  <a-animation attribute="rotation" begin="grab-end" dur="2000" to="360 405 45"></a-animation>
</a-box>
<a-entity progressive-controls="maxLevel: point; pointMixin: point-laser" ></a-entity>
</a-scene>
</body>
</html>

对于控制器,progressive-controls自动检测控制器并设置激光指针,如laser-controls,但使用super-hands手势解释(它还为桌面提供类似光标的输入/纸板用户)。

<a-entity progressive-controls="maxLevel: point; pointMixin: point-laser"></a-entity>

对于目标实体,clickable将其激活为手势接收组件,并定义它将接受哪些按钮事件(如果不需要跨平台支持,则可以删除鼠标事件)。动画触发事件也已更新,以便与super-hands一起使用。

<a-box clickable="startButtons: triggerdown, mousedown; endButtons: triggerup, mouseup" gearvr-trigger='textValue: "New Text Value";' ...>
...
<a-animation attribute="scale" begin="hover-start" dur="300" to="2.3 2.3 2.3"></a-animation>
<a-animation attribute="scale" begin="hover-end" dur="300" to="2 2 2"></a-animation>
<a-animation attribute="rotation" begin="grab-end" dur="2000" to="360 405 45"></a-animation>

对于您的自定义反应组件,我将其更改为对状态更改做出反应,这就是clickable通信已接收到可接受的手势的方式。我还解决了一个范围问题,一旦你有事件触发这个问题你就会抓住它。

    var triggerResponse = function (evt) {
      if (evt.detail.state === 'clicked') {
        message_box.setAttribute('value', this.data.textValue);
      }
    }
    el.addEventListener('stateadded', triggerResponse.bind(this));