Playing attack animations while walking


#1

Hello, I’m fairly new to PlayCanvas but really excited to get started with it. Currently I have a CharacterController that I’ve started working on and a Mixamo character with several imported animations.

The code isn’t super organized, but still readable, I’m currently trying to figure out how to play multiple animations at once. For example, walking while swinging the sword, or walking while unsheathing the sword. Requiring the player to stop during these actions is extremely clunky.

Currently I’m facing two issues which I’m having trouble finding documentation on.

1: Default animation, if an animation is done playing and is not being told to play actively, we should default to the idle state.

2: Playing two animations at once. (Upper and lower body).

var CharacterController = pc.createScript('characterController');

CharacterController.attributes.add('baseSpeed', { type: 'number' });
CharacterController.states = {
    idle: { animation: 'Idle.json' }, 
    strafeLeft: { animation: 'Left Strafe Walking.json' },
    strafeRight: { animation: 'Right Strafe Walking.json' },
    walking: { animation: 'Walking.json' },
    backpedaling: { animation: 'Walking Backwards.json' },
    sheathSword: { animation: 'Sheathing Sword.json' },
    unsheathSword: { animation: 'Withdrawing Sword.json' },
    walkingSword: { animation: 'Run With Sword.json' },
    attack: { animation: 'Standing Melee Attack Downward.json' }
};


CharacterController.prototype.setState = function(state) {
    if(this.state === state) return; 
    
    this.state = state; 
    this.entity.animation.play(CharacterController.states[state].animation, this.blendTime) ;
};

// initialize code called once per entity
CharacterController.prototype.initialize = function() {
    this.force = new pc.Vec3();
    this.blendTime = 0.2; 
    this.setState('idle'); 
    
    this.weaponSheathed = true; 
    
    if (!this.entity.collision) {
        console.error("First Person Movement script needs to have a 'collision' component");
    }

    if (!this.entity.rigidbody || this.entity.rigidbody.type !== pc.BODYTYPE_DYNAMIC) {
        console.error("First Person Movement script needs to have a DYNAMIC 'rigidbody' component");
    }
    
    this.app.keyboard.on(pc.EVENT_KEYDOWN, function(event) {
        if(event.key == pc.KEY_X) {
            if(this.weaponSheathed) this.setState('unsheathSword');
            else this.setState('sheathSword'); 
            
            this.weaponSheathed = !this.weaponSheathed; 
        }
    }, this); 
};

// update code called every frame
CharacterController.prototype.update = function(dt) {
    var speed = this.baseSpeed * dt;
    var vx = 0, vz = 0; 
        
    if (this.app.keyboard.isPressed(pc.KEY_W)) {
        vz = 1;
        this.setState('walking');
    }
    
    if (this.app.keyboard.isPressed(pc.KEY_Q)) {
        vx = +1; 
        this.setState('strafeLeft');
    }
    
    if (this.app.keyboard.isPressed(pc.KEY_S)) {
        vz = -1; 
        this.setState('backpedaling');
    }
    
    if (this.app.keyboard.isPressed(pc.KEY_E)) {
        vx = -1; 
        this.setState('strafeRight');
    }

    // if(vx === 0 && vz === 0) this.setState('idle')
    
    if (this.app.keyboard.isPressed(pc.KEY_SPACE)) {
        jump = true;
    }

    var vol = this.entity.rigidbody.linearVelocity; 
    vol.x = vx * speed;
    vol.z = vz * speed; 
    this.entity.rigidbody.linearVelocity = vol; 
};


This is very basic as I’ve started today, but at-least it shows I’ve been messing with it.


#2

Hi @Genesis38T,

For you 1. question you can do that easily by using a simple state manager to default to an idle animation. The Animation Blending tutorials does exactly that:

https://developer.playcanvas.com/en/tutorials/animation-blending/

  1. That isn’t doable currently, playing two animations at the same time. A PlayCanvas user @whydoidoit has created a system to do that, for an earlier version of the engine, you can read about that here:

https://forum.playcanvas.com/t/released-blend-3d-animation-blending-for-playcanvas-1-0-1/


#3

Thanks for the response, I will surely look into the solution provided by @whydididoit and try to port it to the new engine. It’s disappointing as I see this going back to 2016 that it’s not added to the core yet. This is a huge feature for games.


#4

That is a valid request. Would you like to raise an issue for that in the engine repo?


#5

Done.


#6

Great! Pasting here for reference:


#7

Do you know if PlayCanvas has a bounty system? I would gladly put a $500 bounty on this issue if so.


#8

I don’t think there exists something like that.

You could ask though for a Playcanvas developer to help you implement that by posting in the Jobs category.