1

I'm trying to make a light-switch on the wall in A-Frame control ambient lighting.

I placed actual lights in the scene so I could name them, and use javascript to make the changes.

Since I could not get the game-controler gamepadbuttondown:0 (or 5) to register as an onClick event, I added an animation to the a-entity of the switch itself, and I have an event listener ready to fire off and make the changes.

Everything works on the desktop PC with an actual mouse and an onClick event programmed, but when trying on a phone in a VR headmount with a cheap $5 Mocute controler, I'm stuck.

                <a-entity id="lightswitch" onclick="WorksFineOnPC();" >
                <a-box geometry="height:4.5; depth:4.5; width:.25" position="143 48 14" material="src:https://www.myWebsite/pic.jpg;">
                    <a-animation id="LightAnimation" attribute="rotation" to="0 360 0" dur="100" begin="gamepadbuttondown:0"></a-animation>
                </a-box>
            </a-entity>

Replacing "gamepadbuttondown:0" with "click" works fine on PC, but the onClick function worked fine to start with, and still gives no control with the remote.

The gamepadbuttondown:0 works fine for sounds, as in this example:

<a-entity gamepad-controls
      sound="src: pew-pew.wav;
             on: gamepadbuttondown:7">

Which worked fine with this controller, and others, so the error is somewhere in the animation triggering event.

I plan on shortining the animation to 1 milisecond instead of 100 once it is working. I only included it as a way of starting the event so I could use the event listener to see when "animationend" was emitted anyway. And want it invisible to the user.

I tried using an empty animation, but the box failed to render if I left the type and direction out.

I would like to skip the animation completely if possible, if anyone knows how to trigger an onclick event from the controler using button[x] instead of using the actual mouse. Is there a raycaster solution maybe? Accessing the Three.js under the hood directly?

Ronk
  • 215
  • 2
  • 11

2 Answers2

0

In web browsers, the onclick="foo()" syntax means, when an event fires with the type click, execute the function. Because button presses are not clicks, onclick will be no help to you here.

Instead, you can create a listener for any event type like this:

var lightswitchEl = document.querySelector('#lightswitch');
lightswitchEl.addEventListener('gamepadbuttondown:7', function () {
  console.log('button pressed!');
});

If you want that to be "declarative" in your HTML, just register an A-Frame component to do the listening for you:

AFRAME.registerComponent('my-listener', {
  init: function () {
    this.el.addEventListener('gamepadbuttondown:7', function () {
      console.log('button pressed!');
    });
  }
});

And then:

<a-entity id="lightswitch" my-listener></a-entity>

NOTE: The gamepadbuttondown:7 event is not a normal event created by the browser. It is generated for convenience by the gamepad-controls component.

Don McCurdy
  • 10,975
  • 2
  • 37
  • 75
  • jsfiddle.net/RonK/vm81ddn7/6 - I still haven't gotten it to work. The light-switch is on the right wall near the front. Clicking it with the cursor and a mouse, gamepad buttons do not yet work for me. – Ronk Jun 18 '17 at 22:38
  • I finally got it to work with cursor fusion. Does this have to be disabled for controler clicking to work? (Random drift is making it difficult as well.) – Ronk Jun 18 '17 at 22:47
  • 1
    Hm I see. `gamepad-controls` does not emit events on things the cursor is targeting, only on its own element. With A-Frame 0.6.0 or the current master branch, you might be able to do this: `cursor="downEvents: gamepadbuttondown:7; upEvents: gamepadbuttonup:7;"`. In A-Frame 0.5.0 it's not possible without writing a custom `cursor` component. – Don McCurdy Jun 19 '17 at 04:03
0

@Don McCurdy, Ok, so I left the Fusion-Cursor on, and added an onClick event to "set the subject of focus" with a var.

onclick="SetSubjectOfFocus('light switch');

Then I added 3 different event listeners: moseup, touchend, and button:0 All 3 events will launch the 'to do list' function.

That function will then look at the var assigned to subject of focus, and fire off the desired effect with a checklist of if-then statements.

I was using 'click' but the fusion was causing everything I looked at to be selected automatically. I might add a toggle to leave it on by default for people without a gamepad, but turn it off if a gamepad is detected. (i.e. NOT add event listener, or do add one.)

https://jsfiddle.net/RonK/vm81ddn7/8/

I need to go back at set fusion timeout to 0 so there is no delay, and it does not accidentally click an old item if you are in a hurry.

This could be added to the gamepad-controls.js in the next version. I would recommend using all this on the back-end and in addition to:

<a-entity id="lightswitch" my-listener></a-entity>

and

<a-entity id="lightswitch" onClick="DoSomething();"></a-entity>

you could add:

<a-entity id="lightswitch" OnTriggerEvent="DoSomething();"></a-entity>
Ronk
  • 215
  • 2
  • 11
  • Is everything working, then? You may want to post the suggestions for `gamepad-controls` in a new GitHub issue, so that this answer will be focused on the solution for future readers. :) – Don McCurdy Jun 20 '17 at 15:21