What am I not getting about animation weight blending?

I’ve been having difficulty getting animation blending to work, so I’ve created a simple example. Can someone please explain what I’m doing wrong?

Assume there are two animations on a character… “walk” and “zombie”. (Why zombie? Why not zombie? It’s Halloween.)

Here is code:

function Start () {
	animation["walk"].layer = 2;
	animation["walk"].weight = 1.0;
	animation["zombie"].layer = 3;
	animation["zombie"].weight = 0.5;
	
	animation.Play("walk");
	animation.Play("zombie");
}

By my understanding, this should play zombie at half weight and walk at half weight, but instead, it plays zombie at full weight. Why?

EDIT: To further describe, let’s say I change my code to this:

function Start () {
    animation["walk"].layer = 2;
    animation["walk"].weight = 0.5;
    animation["zombie"].layer = 2;
    animation["zombie"].weight = 0.5;
    	
    animation.Play("walk");
    animation.Play("zombie");
}

Even when I do that, it still plays the “zombie” animation at full weight instead of evenly distributing them. Does anyone know why that might be?

EDIT #2: Changing the order of the animations makes a difference. If the “walk” animation is set to play after the “zombie” animation, the “walk” animation will play instead, at 100% weight.

Still, this doesn’t solve the overall problem of making them blend 50-50.

Each animation layer is handled seperately. A higher layer number has a higher priority. The highest layer is “served” first. When it doesn’t use all weights, the lower layers get their part of the remaining weight.

See the blending weight page.

Also the blend weights are always normalized. When you have two animations on the same layer, one with 1.0 and one with 0.5, the first one will get 0.66666 and the second 0.33333. In this case this layer eats up 100% of the weight.

Here’s another example:

Animation  layer   blendweight   resulting weight
anim1      1       0.2           0.2             ---> remaining weight
anim2      1       0.3           0.3             --->   == 0.5
anim3      0       4 (== 0.4)    0.2 (== 0.5*0.4)
anim4      0       6 (== 0.6)    0.3 (== 0.5*0.6)

Higher layers get the weight first - so it get a much higher proportion. Putting them on the same layer with the same weight would give you half of each. The weights are kind of added up with to get the final proportion. Basically all of it goes to the higher layer.

Finally found a fix. I had to set the weight of the animation AFTER playing it.

function Start () {
    animation["walk"].layer = 2;
    animation["zombie"].layer = 3;
    
    animation.Play("walk");
    animation["walk"].weight = 1.0;
    animation.Play("zombie");
    animation["zombie"].weight = 0.5;
}

Unfortunately, I guess this means that I’ll have to set the weight manually each time. But at least it now makes sense.

I have a question on this… if I have 20 animation files (rotate, move, etc) and the 21th that animates just the intensity (spot light), how could you make layer 1 applying for any animation file on the object… so I can turn them all on and off no matter of what other motion animation is happening around…

I am trying to avoid making a separate scripts for each animation file…

would something like this work?

function Start () {
    animation["walk, walk2, walk3, walk4"].layer = 2;
    animation["zombie"].layer = 3;
 
    animation.Play("walk, walk2, walk3, walk4");
    animation["walk, walk2, walk3, walk4"].weight = 1.0;
    animation.Play("zombie");
    animation["zombie"].weight = 0.5;
}

or other way of not listing all the animation files…

thanks