Thursday, 25 February 2016

Avatar Mask

From the Unity website, an avatar mask allow you to isolate parts of a model's anatomy, allowing the rest to ignore an animation.

In this example, I will take our character model (with animations found here) and get it to aim with his rifle.

To achieve that, I will create an avatar mask which will only affect arms and the head of the model, leaving the rest off it to be animated by the underlying animation. Please note that this example will only work with humanoid types models.

First thing, let's take our model into the scene, and remember to change it's animation type to humanoid. (Fig 1).

Fig 1

For basic movement I will use the same animator controller and scripts used in the Third Person Camera post, so I'm not going to re-explain that part. I reused the script called PlayerMovementImp, found on that post. Also, make a copy of that controller. I removed the parameters we do not need and I added a Boolean called Aim.  (Fig 2)

Fig 2
Do not forget to add a Rigidbody and  CapsuleCollider to our character, so we can move I around with the script.

If you saw the Third Person Camera post, the character is animated with its arm resting when idle, and moving accordingly when walking or running. We will override the arms movement using the mask.

Then, drag in the rifle model. to place it correctly, put the rifle object as a child of the player. More specifically, navigate through all the children of the player model until you find an object called Right_WP. Place the rifle as a child of this object at 0,0,0. (Fig 3).

Fig 3

At this point we can create an avatar mask.

Right click in the project folder, select Create -> AvatarMask.

I gave it the very original name PlayerMask.

Select now the avatar mask just created, open the Humanoid tab, and deselect (by clicking on) the legs, foot IK, the little "circle" you see below the character and the  chest. These body parts should turn red, like in Fig 3.

Fig 4

By doing this, any animation played over this mask will only affect the arms and the head of our model. The red coloured parts are disabled and they will be ignored by that animation, and they will be only affected by the animation in the Base Layer.

Let's click now on the animator controller. Go on the Layer tab, click on the little + icon to create a new layer and let's call it Aim Layer. The settings icon on the right will allow us to select the avatar mask we created. Also, give the variable Weight a value of 1and set the Blending to Override. (Fig 4).

Fig 5

The Weight will determine how much of the animation played in this layer we are going to see. If we leave it to 0, we will see nothing at all, the only animation played will be the one in the Base Layer. You will see in the example scene the effects of this parameter.

By choosing Override, the animation on the Aim Layer will completely override the one from the Base Layer, without any blending.

Select now the Aim Layer. We need to drag in 2 animations: one with the player having the arms resting while holding the rifle and the other one with the arms in aiming position.

Navigate to the folder Military_Rifle_01_Free_v2 -> FBX -> Animation, and drag in the animator the 2 clips called MIL2_M3_W2_Stand_Relaxed_Idle and MIL2_M3_W2_Walk_Aim_F_Loop.  Set the idle one as default.

Remember that we do not care about the legs movement, we simply want the arms movement.

Also, these 2 animations are contained in a FBX object, and we have to change, once again, the animation type to humanoid, for both of them.

From the MIL2_M3_W2_Stand_Relaxed_Idle state in the animator, create a transition to the other animation. Uncheck the HasExitTime box and set the conditions that Aim must be true. Do the same thing the other way, only with an opposite condition. You animator should look like the one in Fig 6.

Fig 6


Now, all we have to do is to feed the animator with the Boolean value for Aim.

In the player movement script, add these few line of code somewhere in the FixedUpdate(), where the rest of the movement take place:



1
2
3
bool aim = Input.GetMouseButton (1);

anim.SetBool ("Aim", aim);

Now we can move the player around just like in the other post. Whenever we hold the right mouse button, the player will go in aiming position.

As you will see in the example scene, the rest of the body moves according to the Base Layer animations, moving the character around just as before. When aiming, only the arms and the head will be affected. If you drag the Weight to 0, the arms will be moved by the animation played in the Base Layer, and they will animate according to the state the character is in.

Example scene here.

1 comment:

  1. Hello,
    Animation is a difficult concept to digest & implement but quite interesting once you get started. And that too with the support of Unity3d Game Engine it is amazing. Very well described article. Keep sharing.

    ReplyDelete