====== Lab 5: Basic Animation Control ====== {{:public:t-vien-15-3:lab5-image.png?600|}} ===== Goal ===== The goal of this lab is to insert a character into a scene that displays animation that changes based on context. This introduces the **Animator** component and the associated **Animator Controller** state machine. ===== Preparation ===== * You should make sure that you have a ready-to-use character and some animations in your project (next to the searcc box in the project view there is a **search by type** icon, press it - without any text in the search box - and select ''AnimationClip'' to see how many animation clips you have). If you don't have a character and animations, you can retrieve a bunch by importing the "Characters" package from the **Assets** menu, or the "Raw Mocap data for Mecanim" package from the asset store. ===== Documentation ===== * The [[http://unity3d.com/learn/tutorials/modules/beginner/animation|beginning tutorials for animation]] in Unity are fairly good, so is the [[http://docs.unity3d.com/460/Documentation/Manual/MecanimAnimationSystem.html|documentation for Mecanim]]. ===== Procedure ===== - **Scene with Character** Create a new scene **OR** if you wish, use an existing scene. You will need to include a ''FPSController'' game object and add a character that is ready for animation, such as ''Ethan'' (from the Characters package) or ''DefaultAvatar'' (from the Mocap package). Set the scene up so that the characer is facing you some distance away. - **Add Animator Component** If the character game object does not already contain an ''Animator'' component, add it. - **Add Animator Controller** In your project browser, go to your own class folder and create a new sub-folder called ''Animation''. In that folder, right-click and select **Create->Animation Controller**. Take this new controller and drag it into the ''Controller'' slot of the ''Animator'' component of your character. - **Create Animation State Machine** Double-click on your animator controller in the inspector panel or open it from the project panel. You should see a new panel similar to the screen-shot above (but only showing one state). Into this panel drag any **two** animations you like (use the 'search by type' method described above to locate animations). They become new states. The first one you drag in will become orange in color, that is the starting state. If you want your character to start with the other animation, you can right-click it and select **Set As Default**. - **Add Transitions** You add a transition from one animation to another by right-clicking on the first of the two animations and selecting **Make Transition**, you then move the mouse pointer over the second animation state and left-click. An arrow should now point from the first to the second. Create one transition one way, and another transition back. Try playing the scene and notice how the character should now start playing the first animation and then the second and then go back to the first continuously. - **Making a Conditional Transition** By default, a transition happens when an animation clip has reached its end. But transitions can also be tied to other conditions. Select the transition from the first animation to the second. Locate the **Conditions** sub-panel in the **Inspector**. There are not many choices there at this time, you will need to create a new state machine parameter to give you more choices. Each new state machine parameter can be used in a condition. There are different types of such parameters, including float values (e.g. modeling a psychological state) and booleans (e.g. modeling a toggle between to modes). We will create a trigger parameter, which in a way behaves like a boolean but does not remain in a true state. It is simply a one-shot "true" event. Using such a parameter as a transition trigger ensures that we only follow the transition once whenever we set this parameter. Locate the **Parameters** panel in the **Animator** view. Press the **+** symbol and select **Trigger**. Give the trigger parameter a name like ''UserPresent''. Then back in the **Conditions** sub-panel of the transition from the first to the second animation, you should now select this parameter. - ** Trigger Transition from Script ** Your newly created animation state machine parameter can now be set from any Unity script, and thus you can affect the state of animation. Back in the regular scene, locate your character game object and add a ''Collision Sphere'' to it, make it a ''Trigger'' and adjust its radius so that it will trigger at a distance about half the way between you (the first person controller) and the character. Add a new scrip to the character that intercepts the trigger event (''void OnTriggerEnter(Collider col)'') and **set the UserPresent trigger parameter** in the animator controller. You do that by first acquiring a reference to the ''Animator'' component (hint: Use ''GetComponent''). Then on that component you call ''SetTrigger("UserPresent")''. Check out the [[https://docs.unity3d.com/Documentation/ScriptReference/Animator.SetTrigger.html|documentation for ''SetTrigger'']]. If everything is working properly, you should now see the transition from the first to second animation when you walk towards the character. Make sure that the second animation only plays once and then returns to the first animation (until you cross the trigger boundary again). - **OPTIONAL: Optimize** Searching for the ''Animator'' component every time you want to access its ''SetTrigger'' method is not fast. Also, it is not particularly fast to set the trigger by name, i.e. the state machine has to search for the matching string for that parameter before setting its value. Instead you can pre-calcualte the hash ID for this parameter and pass that id into the function. So, to optimise do two things: Store a reference to the animator component AND a hash id value for the parameter you want to change as member variables in your behavior script. Only assign values to these two variables once.