[SOLVED] On Screen Buttons to Control Player Movement

Hello!

I’m making a variation of the Food Run Tutorial and want to add buttons on screen that controls the player’s movement as I want my game to be played primarily on mobile. The tutorial currently controls the player’s movement with WASD keys.

I have zero background in Java and coding in general as I’m a 3D artist so please be patient with me!

https://playcanvas.com/editor/project/977745

I’m currently trying to make the “wButton” work in the PlayerController script.

Thanks in advance!

Hi @Vivian_Chou You were mostly there with what you had done in the PlayerController script. You needed to add a function to call in your script. Here is what I added.

/**
 * Initialize - setup internal state, resources, listeners.
 */
PlayerController.prototype.initialize = function() {
    this._anim = this.animEntity.anim;
    this._angle = 0;
    this._input = true;
    this.wButton.element.on('click', this.wButtonPressed, this);

    // create a single Vec3 for frame to prevent creating a new Vec3 every frame
    this._frameMovement = new pc.Vec3();
};


PlayerController.prototype.wButtonPressed = function() {

    console.log("WButton");

};

You can add your action inside or capture the on screen button used and feed your player movement script. The console.log prints out to the web browser console the text when pressed.

Here is a screen shot of my debugger window. Most web browsers support a debugger or an inspector. Many, you just simply hit F12 or right click the mouse on the page and select “inspector”. There may be more explanation in this forum on how to use this. Or you could do a quick web search.

Welcome to the community!

2 Likes

Hi @Tirk182,

Thank you so much for such a quick and kind reply.

I’ve been trying to capture the on screen button and feed it to the player’s movement but I’ve hit another road block. The inspector doesn’t seem to show anything too exciting.

After many different variations this is what I have so far that doesn’t come up with errors:

var PlayerController = pc.createScript('playerController');

/** Attributes */

PlayerController.attributes.add('animEntity', { type: 'entity' });

PlayerController.attributes.add('power', { type: 'number', default: 450000 });

PlayerController.attributes.add('wButton', { type: 'entity', description: 'this controls forward movement when pressed'});

/** Lifecycle Methods */

/**

 * Initialize - setup internal state, resources, listeners.

 */

PlayerController.prototype.initialize = function() {

    this._anim = this.animEntity.anim;

    this._angle = 0;

    this.wButton.element.on('click', this.wButtonPressed, this);

};

PlayerController.prototype.wButtonPressed = function() {

    console.log("WButton");

};

/**

 * Update - called once per frame.

 *

 * @param {number} dt - time (in seconds) since last frame.

 */

PlayerController.prototype.update = function(dt) {

    // movement

    var x = 0;

    var z = 0;

    // Check for key presses

    if (this.app.keyboard.isPressed(pc.KEY_A)) {

        x += 1;

    }

    if (this.app.keyboard.isPressed(pc.KEY_D)) {

        x -= 1;

    }

    if (this.wButtonPressed.isPressed) {

    console.log("WButton2");

        z += 1;

    }

    if (this.app.keyboard.isPressed(pc.KEY_S)) {

        z -= 1;

    }

@Vivian_Chou I have come up with a quick solution that I am not all that excited about but I am not going to be available for a few days and wanted to get something to you. This is what I did for the WButton only. It is not a very elegant solution so I am hoping you play around and do some more searching for better solutions. A lot of this has to do with just a on screen button and how it reacts.

var PlayerController = pc.createScript('playerController');

/** Attributes */
PlayerController.attributes.add('animEntity', { type: 'entity' });
PlayerController.attributes.add('power', { type: 'number', default: 450000 });
// Replicate this for other buttons and give different name
PlayerController.attributes.add('wButton', { type: 'entity', description: 'This controls foward movement when clicked'});
/** Lifecycle Methods */
// Replicate this for other buttons and give different name
let wBFlag = false; // << W Button Flag

/**
 * Initialize - setup internal state, resources, listeners.
 */
PlayerController.prototype.initialize = function() {
    this._anim = this.animEntity.anim;
    this._angle = 0;
    this._input = true;
    this.wButton.element.on('click', this.wButtonPressed, this);


    // create a single Vec3 for frame to prevent creating a new Vec3 every frame
    this._frameMovement = new pc.Vec3();
    
};

// Replicate this for other buttons and give different name
PlayerController.prototype.wButtonPressed = function(dt) {

    console.log("WButton");
    wBFlag = true;
                
    setTimeout(function() {  
        wBFlag = false;
    },400); // < Not good practice trying to simulate key. 

};


/**
 * Update - called once per frame.
 *
 * @param {number} dt - time (in seconds) since last frame.
 */
PlayerController.prototype.update = function(dt) {
    // movement
    this._frameMovement.x = 0;
    this._frameMovement.z = 0;

    // Check for key presses
    if (this._input) {
        if (this.app.keyboard.isPressed(pc.KEY_A)) {
            this._frameMovement.x += 1;
        }

        if (this.app.keyboard.isPressed(pc.KEY_D)) {
            this._frameMovement.x -= 1;
        }

        if (this.app.keyboard.isPressed(pc.KEY_W) || wBFlag == true) { // << Look for flag or Key
            this._frameMovement.z += 1;
        }

        if (this.app.keyboard.isPressed(pc.KEY_S)) {
            this._frameMovement.z -= 1;
        }
    }

    // use direction from keypresses to apply a force to the character
    if (this._frameMovement.x !== 0 || this._frameMovement.z !== 0) {
        this._frameMovement.normalize().scale(this.power * dt);
        this.entity.rigidbody.applyForce(this._frameMovement);

        // set the speed
        this._anim.setFloat('Speed', this.entity.rigidbody.linearVelocity.length());

        // rotate the model
        const newAngle = 90 - (Math.atan2(this._frameMovement.z, this._frameMovement.x) * pc.math.RAD_TO_DEG);
        this._angle = pc.math.lerpAngle(this._angle, newAngle, 0.4) % 360;
        this.animEntity.setEulerAngles(0, this._angle, 0);
    } else {
        this._anim.setFloat('Speed', 0);
    }
};

Let me know how this works for you and good luck with your project. Please respond to this post so I can see your status.

@Tirk182
You are an ABSOLUTE life saver.
I honestly didn’t know what else to do if it weren’t for you.

Thank you

2 Likes