Character controller on Input

Hey guys,

I am currently working on a 2d project which involve a character that the user is controlling. For now the only way I found to control this character is using the update function in a script waiting for inputs and updating the character position (see below).

I have been looking at different script for controlling characters and always found this way of doing things. However, I am not really satisfied with it because it means that when the user is not giving any input the function update is still running. Is there a way to update the position of my character only on user’s inputs? Maybe by mixing the event EVENT_KEYDOWN and isPressed(key) however I would need to have the delta time that the function update has. Hopefully we can find a way to improve this script!

Thank you for your help

Hi @Ougogogadget,

That’s good thinking. You can use keyboard events as shown in this tutorial:
https://developer.playcanvas.com/en/tutorials/keyboard-input/

Now when a key is down, don’t move the character directly in your input handler, just set a script wide property to true. Example:

KeyboardHandler.prototype.initialize = function() {

    this.input = {
        left: false,
        right: false
    };

    this.app.keyboard.on(pc.EVENT_KEYDOWN, this.onKeyDown, this);
    this.app.keyboard.on(pc.EVENT_KEYUP, this.onKeyUp, this);
};

// update code called every frame
KeyboardHandler.prototype.update = function(dt) {

    if(this.input.left){
        // do things
    }
};

KeyboardHandler.prototype.onKeyDown = function (event) {

    if (event.key === pc.KEY_LEFT) this.input.left = true;
    if (event.key === pc.KEY_RIGHT) this.input.right = true;
};

KeyboardHandler.prototype.onKeyUp = function (event) {
    if (event.key === pc.KEY_LEFT) this.input.left = false;
    if (event.key === pc.KEY_RIGHT) this.input.right = false;
};

You can now use the input in your update loop together with the delta time. That way you can also use the same object with other types of input e.g. mouse or gamepad.

It works, thank you!

is there a way that I can add a running function to the character controller? I’m new to play canvas.

Hey @cliff,
You can add a running function to the character controller. First you need to define a key that will trigger the character to run, for example shift. Then you need to listen to the event of the key being pressed down and up. When the event happens, you must modify a state within your script. The final step is to translate (i.e. move) your character further away if he is running. I hope the script below will help you.

KeyboardHandler.prototype.initialize = function() {

    this.input = {
        left: false,
        right: false
    };
   // Step 3: modify a state
   // store the is running state to know if your character is running
   // by default the character is not running
   this.isRunning = false


    // Step 1: listen to event
    this.app.keyboard.on(pc.EVENT_KEYDOWN, this.onKeyDown, this);
    this.app.keyboard.on(pc.EVENT_KEYUP, this.onKeyUp, this);
};

// update code called every frame
KeyboardHandler.prototype.update = function(dt) {

    if(this.input.left){
        // do things
    }

   // Step 4: increase the translation
   // please refer to the original post to update the translation
   var speed = 1;
   // if is running
   if (this.isRunning){
        // multiply speed by 2
        speed *= 2;
  }
  var translation = new pc.Vec3(....).nornalize().scale(speed * dt);
};

KeyboardHandler.prototype.onKeyDown = function (event) {

    if (event.key === pc.KEY_LEFT) this.input.left = true;
    if (event.key === pc.KEY_RIGHT) this.input.right = true;
    // Step 2.1 : handle the event the down event
    if (event.key === pc.KEY_SHIFT) this.isRunning = true;
};

KeyboardHandler.prototype.onKeyUp = function (event) {
    if (event.key === pc.KEY_LEFT) this.input.left = false;
    if (event.key === pc.KEY_RIGHT) this.input.right = false;
    // Step 2.2 : handle the event the up event
    if (event.key === pc.KEY_SHIFT) this.isRunning = false;
};
1 Like

do I add the code to the controls the collision mesh or the camera?
and I’m not to good with coding… at all

Hey @cliff, I suppose you want to move your character, so the code I sent you before does not belong to the camera. I guess you should have a script named something like “Controller…” or “Movement…” on the entity that you want to control. After the calculation of your translation you will more likely want to move the entity the script is attached too, like below

// update code called every frame
KeyboardHandler.prototype.update = function(dt) {
  // your code before
  ...
  // create translation Vector 3D
  var translation = new pc.Vec3(....).normalize().scale(speed * dt);
  // translate the entity the script is attached to
  this.entity.translate(translation);
};