Implementing walking script

Hello,

I am a junior front-end developer and very new in javascript so I apologize in advance if my question is too silly. I just thought playcanvas would be a good way to learn more about javascript and here I am.

I am building my first demo to try and work things out and I have already stumbled upon an issue.
This is my editor link: https://playcanvas.com/editor/scene/926987.

I got an iddle animation going on while my character is waiting, but I would like to swap to the walking animation when I hit the arrows that move her. I also thought my character should rotate left or right before turning on those directions but when my rotation starts it just goes on forever. I just want it to happen while the button is pressed.

I hope what I am trying to do makes sense and again sorry if this is too simple to solve, I am just too new in javascript and that’s the reason why if someone has a solution for my issues I would also like an explanation so that I can understand what’s going on and what I did wrong.

Please let me know if you need any more links from me.

Thanks

Hi @Nick_Kalfas and welcome,

Nice assets! To your question, you can disable the Loop property on your animation component:

image

If you do that, then each time you call the animation play method it will play the relevant animation only once. Here is one way to do that:

Walking.prototype.initialize = function() {
   this.activeAnimation = 'idle';
};

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

    var newAnimation = 'Great Sword Idle.json';    
    var blendTime = 0.3;

    if (window.keyboard.isPressed(pc.input.KEY_W)){
        this.entity.translate(0, 0, -0.1);     
        newAnimation = 'Great Sword Walk.json';
    }
    
    if (window.keyboard.isPressed(pc.input.KEY_S)){
        this.entity.translate(0, 0, 0.1);
        newAnimation = 'Great Sword Walk.json';
    }
    
    if (window.keyboard.isPressed(pc.input.KEY_A)){
        this.entity.translate(-0.1, 0, 0);
        newAnimation = 'Great Sword Walk.json';
    }
    
    //ROTATION
    
    if (window.keyboard.isPressed(pc.input.KEY_D)){
        angle = -2;
        this.entity.translate(0.1, 0, 0);
        newAnimation = 'Great Sword Walk.json';
    }
    
    if (window.keyboard.isPressed(pc.input.KEY_A)){
        angle = 2;
        newAnimation = 'Great Sword Walk.json';
    }
    
    this.entity.rotateLocal(0, angle, 0);

    if( this.activeAnimation !== newAnimation){ 
       this.activeAnimation = newAnimation;
       this.entity.animation.play(this.activeAnimation, blendTime);
    }
    
};

In the same way you can add more animations and build a more complex state manager.

If you would like to always fallback to idle, then keep the Loop property enabled.

Update: code updated to avoid unnecessary calls to animate.play()

Hi @Leonidas and thank you for your reply.

I have added your code but now I get a “this.entity.animate is undefined” error when I run it.

I also don’t understand where do we declare what “idle” and “walk” are? Should I create a variable at the top for this?

That is the name of the animation asset that you request to play each time. In your case it would be:

Instead of 'walk' put "Great Sword Idle.json"
Instead of 'idle' put "Great Sword Walk.json"

e.g.
this.entity.animation.play('Great Sword Walk.json');

You can see the animations you have attached and their name on the animation component:

image

Regarding your error I’ve made a typo on my code above on line 48 of your script. It’s now fixed and I’ve updated your animation names as well.

Updated a property on the code posted above to fix a second undefined error.

Yeah I was preparing a question about that haha, cheers.

However the rotation still goes infinite even though you got “isPressed” in the code. I think that would only mean that it would run only while the button is pressed?

Now, for that you need to start your angle calculation from a zero value. Move this line:

var angle = 0;

Inside your update method, so each time the update callback is being executed your code will start from a 0 angle rotation and increment only if the right key is pressed.

Walking.prototype.update = function(dt) {
   var angle = 0;

   // ...

    //ROTATION
    
    if (window.keyboard.isPressed(pc.input.KEY_D)){
        angle = -2;
        newAnimation = 'Great Sword Walk.json';
    }
    
    if (window.keyboard.isPressed(pc.input.KEY_A)){
        angle = 2;
        newAnimation = 'Great Sword Walk.json';
    }
    
    this.entity.rotateLocal(0, angle, 0);
}

yp, that did do it! thank so much.

This is really frustrating. Now that I see your code writen down it does make sense to me. It’s kind of self explanatory, but I would have never thought of building it myself…

Thank you so much for your time and your help on this.

1 Like

There is a major effort in updating the Playcanvas docs to help on that. If you have some feedback to provide that would be most welcome:

https://forum.playcanvas.com/t/documentation-feedback-wanted-what-would-you-like-to-see-improved/13607/7

I’ll keep that in mind. I think it’s mostly due to my inexperience with javascript but yeah maybe I can add a few notes as a newbie…

Thanks a bunch!

1 Like