Adding Events To Controller

Is this legal:

    this.controller = new pc.input.Controller(window);
    pc.events.attach(this.controller);
    
    this.controller.registerKeys('prevCamera', [pc.input.KEY_LEFT]);
    this.controller.registerKeys('nextCamera', [pc.input.KEY_RIGHT]);

    this.controller.on('prevCamera', this.onPrevCamera);
    this.controller.on('nextCamera', this.onNextCamera);

For some reason I’m not getting the events.

The Controller is being created in the constructor, and the registerKeys is being called there too. However, the event listeners are being added in the initialize function.

No, the pc.input.Controller doesn’t fire events.

You check for actions like the keyboard:

this.controller.isPressed("prevCamera");

You can see the code here: https://github.com/playcanvas/engine/blob/master/src/input/input_controller.js

Thanks Dave. That was my workaround. Would event handlers make sense for controller? They do work for keyboard/mouse.

Btw, I might have ran into a bug. If I instantiate an array in the constructor the contents get lost:

    //this.cameraList = new Array("Level-01", "TestBellHuey");

If I instantiate it during the initialize call it is persistent. Is that expected behavior? If so, is there a list of do’s and don’ts for the constructor? Or am I doing something wrong?

Nothing should be overwritten in the constructor unless you have declared this.cameraList as a script attribute. In which case, yes, it will be overwritten with contents from the editor.

The only “don’t” for the constructor is that the hierarchy isn’t present when the constructor is called. So you can’t access the hierarchy from context.root (e.g. use context.root.findByName) in the constructor. You have to wait until initialize() to access the hierarchy.

I’m not super happy with the controller at all it could do with some TLC. Events might make sense in the controller, but if you are just assigning multiple keys to an action. It might make more sense to use the “keydown” event and watch for the key codes in there.

Guilty as charged. Thanks again Dave.

Yes, I initially wanted to have a list of entity names accessible from the development window but learned arrays of strings, or arrays of entity’s wasn’t possible. So I just hardcoded the list and the rest is history. . .

After removing the attribute, the array instantiation in the constructor worked as expected.

Not accessing the hierarchy during the constructor makes sense. Thanks for pointing that out. I’m sure I’ll forget by tomorrow though :smiley:

For the record, I’m just playing with reparenting the camera to different objects in the scene. I’m using wasPressed but getting numerous calls (frame, by frame). wasPressed and isPressed should be different, yes? If I press the key and let go, should that match a wasPressed?

wasPressed is true once if the key was pressed last frame. isPressed is true for every frame that the key is held down.

Then how many times should this be true?

        if(this.controller.wasPressed('prevCamera')) {
            this.onPrevCamera();
        }

It appears to fire each frame. If I understood correctly, wasPressed should be true only once.

Is my declaration correct:

    this.controller.registerKeys('prevCamera', [pc.input.KEY_LEFT]);

EDIT:
Btw, I believe I’ve seen it both ways: pc.input.KEY_LEFT, pc.KEY_LEFT.

Which is the correct syntax. They both seem to have the same behavior.

You need to be make sure you are calling this.controller.update(dt) every frame.

Thanks Dave. It turns out I had to place that line after the check, otherwise my conditional test would always fail. Is that a correct statement?

The controller.update() method needs to be run once every frame for the checks to work correctly.

So yes, just put it somewhere in your script update function and that should be fine.

    update: function (dt) {
        
        this.controller.update(dt);
        
        if(this.controller.wasPressed('prevCamera')) {
            this.onPrevCamera();
        }
        
        if(this.controller.wasPressed('nextCamera')) {
            this.onNextCamera();
        }
        
        //this.controller.update(dt);
    },

As is the above function won’t work. If I comment out the top line and uncomment the bottom line, it will work.