Animator's parameters are variables that are defined within the animation system but can also be read and store values from scripts. Default parameter values can be set up using the Parameters widget in the bottom-left corner of the Animator window when you create them. They can be of the following four types:
- Vector: A point in space (x,y,z)
- Int: An integer (whole) number
- Float: A number with a fractional part
- Bool: This refers to true or false
Parameters can be assigned values from a script using the methods in the Animator class: SetVector , SetFloat , SetInt , and SetBool, while they can be accessed (read) with the GetVector, GetFloat, GetInt, and GetBool methods. Create a float type parameter and call it Speed. As you can see, the default value can be specified, so leave it as 0.0. Now, press the connecting line and, finally, note that you can choose the parameter Speed from the drop-down menu. Choose when value is greater than and put 0.1 in the box.
The character stays in Idle forever again, but is waiting for scripts (user input in this case) that change the speed value to make the character walk. Create a float parameter; we will call it Turn. Create a new component script by clicking on the Add Component button after the last component in the Warrior GameObject in scene. Name the class SimpleThirdPersonCharacter.
Let's kick off by declaring a private variable that we can utilize throughout the script, referring to our Animator component:
private Animator currentAnimator;
Define a float variable to store runMultiplier to apply it when the Shift key is kept pressed and specify a default value (walking) of 0.5f:
float runMultiplier = 0.5f;
We could have declared this variable as public, as we previously did, in Chapter 3, Creating and Setting Game Assets, to allow the dragging of the respective GameObject from the Scene Hierarchy into our Component slot. For learning purposes, we will now retrieve a component at runtime instead, without the need to drag the component on the script, as we usually do.
Additionally, the component we want to retrieve is on the same GameObject that this script will be executed from.
This can be useful when we want to set the value of the variable at runtime or because the value might change and we want to retrieve a particular object component seeking in the scene by name or by tag (refer to Chapter 8, AI, NPC, and Further Scripting).
Unity allows us to make everything from code or with a lot of help from the editor; it is your choice. Whether you are a skilled coder or a graphic designer, you choose the path you prefer for these kinds of things. As the Animator component, we want to track with this variable on to the same GameObject that is driving our C# class component; it is just simpler this way.
Define these variables by writing the following code at the top of the SimpleThirdPersonCharacter class:
using UnityEngine;
public class SimpleThirdPersonCharacter : MonoBehaviour {
Animator currentAnimator;
float runMultiplier = 0.5f;
// Use this for initialization
void Start () {
currentAnimator = GetComponent<Animator>();
}
Next, we will write the Update() method:
// Update is called once per frame
void Update ()
{
//if(Input.GetAxis("Horizontal")>0)
float verticalForce = Input.GetAxis("Vertical");
float horizontalForce = Input.GetAxis("Horizontal");
float absVertForce = Mathf.Abs(verticalForce);
// Run if Shift is kept pressed
if(Input.GetKeyDown(KeyCode.LeftShift) ||
Input.GetKeyDown(KeyCode.RightShift) ) runMultiplier = 1.0f;
if(Input.GetKeyUp(KeyCode.LeftShift) ||
Input.GetKeyUp(KeyCode.RightShift) ) runMultiplier = 0.5f;
//Debug.Log("user input: horizontal="+horizontalForce+"
vertical="+ verticalForce);
currentAnimator.SetFloat("Forward", absVertForce*runMultiplier);
currentAnimator.SetFloat("Turn",horizontalForce);
// Because we don't use RootMotion on this prefab, we need to
both translate and rotate him directly from user input data
transform.Translate( transform.InverseTransformVector(
transform.forward *( verticalForce * runMultiplier *0.075f)) );
if(Mathf.Abs(horizontalForce)>0.1f) transform.Rotate
(transform.up, horizontalForce*2f);
}
This code will read in arrow keys and Shift key to apply a force to the character directly. Press play and you should see the character walk and move forward when you press the UP arrow key. We have just given a quick look to the old legacy animation system and on how to import .fbx file for the new Animator, and how to drive quickly an Animator setup with in-place animations. Now, it's time to dive into the best option for modern character animation with Animator: Root-Motion animation.