Confusion about animation blending

Could anyone could teach me how animation layers and blending works exactly? I tried to follow documentation but got stuck. What I want is to be able to walk clap (using upper body mask) at the same time. For this I created 3 projects and got different problems in each.

  1. PlayCanvas | HTML5 Game Engine
    This is setuped with two layers of animation and trigger parameters. On “Z” press it should make boolean “clap” = true. This should activate animation of layer “topbody”. Here I met multiple problems:
  • if mask for “topbody” is not set and blend type is overwrite, animation switches to clapping, but it then stays in that layer and does not go back to base layer animations.
  • if mask for “topbody” is set and blend type is additive or overwrite, then animation is not visible regardless of what weight values I set or blend types I set. However in console you can see that event that fires when animation starts actually is triggered.
  1. PlayCanvas | HTML5 Game Engine
    This project I created to confirm if problems with blending comes from mixamo bones names. This one just use same “strafe” animation when Z button is pressed. However the behavior is the same, as in previous project. When mask is set, animation is not visible regardless of values on editor animation graph. So this just to make sure if that is caused by mixamo animations or bones names.

Before 3rd project I need to make some things more confusing. Using same setup before I was able to make this half working: Mask correctly worked and clapping animation as orking only for upper body, but as before the animation did not go back “Base” layer. I am not sure why it does not work at all anymore with mask. But then if additive blend option was selected instead of overwrite the clapping animation ended up looking like this, which is not okay:

  1. PlayCanvas | HTML5 Game Engine
    At this point I gave up with editor animation graphs and try to implement (PlayCanvas Examples). Here press “Z” = to walk, “X” = to idle and “C” = for clapping. But met with new problems:
    In example upperBodyLayer.transition(value, 0.4); start animation ith transition, how ever for me
    this.upperBodyLayer.transition("Clap", 0.4); in playermovement script does nothing at all. I also added events to console out if “Clap” animation starts.

So in the end sitation that I am stuck for days with both approaches. I personally would like to complete 1st) approach, as it would make my life easier on multiplayer part of the code. But if 3rd) method would work that would also be great. I might be missing some core element somewhere or some rules I need to follow. I would be very greatfull for guidlines!

P.S. thank you for reading this wall of text.

Yet another update. Found a reason of mask not working at all: if you have two layers and create mask for one it ill save that mask and will not let you chang root bone. if you change root bone mask is still cashed and will not react to it. So if you change anything you need to delete all the masks and remake them. And if you have two layers and you change root bone, it does not update for second layer mask layer selection even if you remove and add new mask! this is a bug my guess.

I will update 1) example with this knowledge. But now I am back to position where if it sets to “additive” it makes that weird behavior when bones that are selected in mask scales down. So obviously there are something else there I am missing. At the begining I thought it might be case because of animation having different scale on bones, but that does not seem to be a case because:

  1. If claping animation is running on same layer, the scale is correct.
  2. I applied scale on all animations and mesh on blender and exported to clean project which have same behavior.

I’d say the best way to understand what is going on is to step into the engine source code with a debugger to explore what is happening. Not a simple task I’m aware.

After some investigation with 3rd example (one that everything is done via code) I found something that should not be there:

If I create a layer for anim component:

 this.upperBodyLayer = this.entity.anim.addLayer(
        'UpperBody',
        this.blend,
        upperBodyMask,
        pc.ANIM_LAYER_ADDITIVE
        //pc.ANIM_LAYER_OVERWRITE
    );

This code should add UpperBody layer to anim component. That would mean

console.log("-upperBodyLayer state = : " + this.upperBodyLayer.activeState);

and

console.log("-upperBodyLayer state = : " + this.entity.anim.findAnimationLayer("UpperBody").activeState );

should return same value. However second line of code return active state of Base layer instead of UperBody layer.

As if layers are created via Editor, the active state is returned correctly. Is this considered a bug? or somehow it is intentional?

try stepping into this.entity.anim.findAnimationLayer("UpperBody") to see what it does and why it is different.

Hello,

Then I would like to report a bug:

https://playcanvas.com/project/1216249/overview/anim-layer-bug

Adding layer via code seems to overwrite Base layer temporary.

var upperBodyLayer = this.entity.anim.addLayer(
        'UpperBody',
        this.blend,
        upperBodyMask,
        pc.ANIM_LAYER_ADDITIVE
        //pc.ANIM_LAYER_OVERWRITE
    );

After adding layer logs shows that baseLayer name becoms added layer name. However if you assign any animation it becomes a mess.

-----------------------BEFORE ASSIGNING ANIMATION----------------------
this.entity.anim.baseLayer.name= : UpperBody
upperBodyLayer.name= : UpperBody
this.entity.anim.findAnimationLayer(`UpperBody`).name = : UpperBody

this.entity.anim.assignAnimation(“ClapAnim”, this.clapAnim.resource);
Animation layers are corrupted after assigning animation via code.

----------------------AFTER ASSIGNING ANIMATION----------------------
this.entity.anim.baseLayer.name= : Base
upperBodyLayer.name= : UpperBody
this.entity.anim.findAnimationLayer(`UpperBody`).name = : Base

That follows transitions don’t work and other weird behavior.

1 Like

And lets make it second bug report:

https://playcanvas.com/project/1215543/overview/breaking-the-rig
ANIM_LAYER_ADDITIVE
Anim component additive layer mode does not work correctly if anim component is not on entity with Render component. If Anim component is on different entity than Render component, then animations in same Base layer works correctly, but if you add another layer and set blend type to additive weird scaling behavior happens:

image

Same behavior happens if you do it over editor or doing everything via code.

1 Like

Do you set up the root bone property to point it to the root bone? That might help with the second issue.

With the first issue, I had a quick look at the code and it seems the new layer is just added to the end of the list, so it should not modify any layers already in the list. But I have not had time to investigate deeper.

Thank you for your response.

I have tried multiple root bone combinations. It either don’t work at all or this behavior. Plus wrong root bone should effect Base layer as well, isn’t it? But in this example weird behavior appears only on non base layer. Also Overwrite blend mode should be effected as well, but it isn’t.

At least now I know what causes it and how to work around.