- Home /
How to add two animations?
Hi, I have an avatar controller which handles some animations (walk, idle, jump, salute).
I want to salute while I'm idle or walking so the way I'm doing it is:
public Transform mixBone;
animations[walk.name].layer = -1;
animations[idle.name].layer = -2;
animations.SyncLayer(-1);
animations[walk.name].normalizedSpeed = 1;
animations[jump.name].layer = 5;
animations[jump.name].wrapMode = WrapMode.ClampForever;
animations.SyncLayer(5);
animations[salute.name].layer = 5;
animations[salute.name].wrapMode = WrapMode.Once;
animations[salute.name].blendMode = AnimationBlendMode.Blend;
animations[salute.name].AddMixingTransform(mixBone);
And then this is my update():
if(!motor.IsMoving())
{
animations.Blend(walk.name, 0.0f, 0.3f);
animations.CrossFade(idle.name);
}
else
animations.CrossFade(walk.name,0.3f);
}
}
And....
void DidSalute()
{
animations.Blend(salute.name,1);
}
Which is called when an input key is pressed.
I don't know why... but it seems that salute is executed but it's overrided by the walk/idle animation and the salute animation doesn't finish.
Maybe because of the Update() crossfade¿?
EDIT:
It works with BlendMode.Blend.
http://unity3d.com/support/documentation/Manual/Character-Animation.html
http://unity3d.com/support/documentation/ScriptReference/Animation.html
Answer by Owen-Reynolds · Aug 24, 2011 at 09:22 PM
Two problems. One is your salute is probably short enough that the fade in/out overwhelms it. Blend with a weight of 1.0 works the same as Crossfade. It fades in, then out (for a PlayOnce,) with a default fade in/out time of 0.3 seconds, at each end. For a looping walk, that's fine. For a 1 second salute, that leaves only the middle 4/10ths playing normally. In other words, at 70% of the way there, it says "time to start heading back."
Try shortening the fade-in time: CrossFade("salute" , 0.05f);
or Blend("salute",1 , 0.05f);
0.05 doesn't seem like much, but at 60fps, it's 3 frames.
The other problem is what the previous answer refers to. You have salute set as an "ADD" animation. Adds play on top on other animations. Salute played as normal (blend) says to put your hand in an exact spot, overriding other animations. Played as an add, it says to twist your arm 180 degrees from where-ever it is and bend your hand an extra 90 degrees. That will gladly put your hand behind your back, as you arm continues to "walk pump."
ADD is one way to solve the problem of "how do I combine idle and salute?" For a shiver, say, it's perfect. For the salute, you probably want only the arm to salute anyway, while the rest of the bones play idle/walk. Leave salute as normal (blend) (but it won't blend since weight is 1,) keep it on a higher layer, but limit the bones:
// drag rightArmbone into Inspector on this:
public Transform rightArmBone;
// or, don't drag and in Start:
rightArmBone = transform.Find("bones/chest/Rshoulder/RupperArm") as Transform;
// either way:
animation["salute"].AddMixingTransform(rightArmbone);
// playing salute now animates only upperArm and its children,
// lets lower level animation (idle/walk) control other bones
Also, SynchLayer is used to force multiple animations on one layer to have the same times (if you have a 1 and 2 second animation on layer 4, SynchLayer(4) sets them both to 1.5 secs.) I think it's a bit of a red herring in your code -- you only call it when a layer has one animation, and I doubt you want jump and salute to synch up. It's useful for averaging animations, which is the 3rd way of playing two at once.
Answer by roamcel · Aug 24, 2011 at 03:31 PM
What you need is a specific approach which is somewhat difficult to explain and understand, but which is exactly what you need.
It basically allows one animation to affect only a subtree of the armature. In this case for example, if the salute is performed with the right arm, you should apply it to the right shoulder.