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!
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.
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;
};
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);
};