Animation Systems¶
Animator Controller¶
The Animator Controller is Unity's primary animation state machine. It manages states, transitions, parameters, layers, and blend trees.
States and Transitions¶
- Each state plays an Animation Clip or Blend Tree
- Transitions define conditions for switching between states
- Use "Has Exit Time" for animations that must complete (attack finishers)
- Disable "Has Exit Time" for instant transitions (idle to run)
Parameters¶
Control transitions from scripts using parameters:
private Animator _animator;
private void Awake()
{
_animator = GetComponent<Animator>();
}
private void Update()
{
_animator.SetFloat("Speed", _currentSpeed);
_animator.SetBool("IsGrounded", _isGrounded);
}
public void Attack()
{
_animator.SetTrigger("Attack");
}
Parameter types: SetFloat, SetBool, SetInteger, SetTrigger.
Triggers reset automatically after the transition fires. Bools persist until explicitly changed.
Blend Trees¶
Blend between multiple animations based on parameters: - 1D Blend Tree: walk to run based on speed - 2D Freeform: directional movement blending (strafe, forward, backward) - Direct: explicit weight control per child motion
Layers¶
Use layers for independent animation on different body parts: - Base Layer: locomotion (full body) - Upper Body Layer: aiming, shooting (override or additive blending) - Face Layer: facial expressions (additive)
Set layer weight with _animator.SetLayerWeight(layerIndex, weight).
Animation Events¶
Call methods from specific frames in an animation clip:
public void OnFootstep()
{
_audioSource.PlayOneShot(_footstepClip);
}
public void OnAttackHit()
{
DealDamageInRange();
}
Add events in the Animation window by selecting a frame and clicking "Add Event."
Root Motion vs Scripted Movement¶
- Root Motion: Animation drives the transform. Enable "Apply Root Motion" on Animator. Good for realistic character movement where animation artists control locomotion.
- Scripted Movement: Code drives the transform; animation is cosmetic. Disable "Apply Root Motion." Better for precise gameplay control.
Use OnAnimatorMove() to customize how root motion is applied:
private void OnAnimatorMove()
{
Vector3 velocity = _animator.deltaPosition / Time.deltaTime;
_rb.linearVelocity = new Vector3(velocity.x, _rb.linearVelocity.y, velocity.z);
}
Inverse Kinematics (IK)¶
Use OnAnimatorIK to adjust limb positions at runtime:
private void OnAnimatorIK(int layerIndex)
{
if (_lookTarget)
{
_animator.SetLookAtWeight(1f);
_animator.SetLookAtPosition(_lookTarget.position);
}
if (_rightHandTarget)
{
_animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
_animator.SetIKPosition(AvatarIKGoal.RightHand, _rightHandTarget.position);
}
}
Requires a Humanoid avatar and an Animator Controller with IK Pass enabled on the layer.
DOTween / LeanTween¶
For procedural, code-driven animation:
// DOTween examples
transform.DOMove(targetPosition, 1f).SetEase(Ease.OutQuad);
transform.DOScale(Vector3.one * 1.5f, 0.3f).SetLoops(2, LoopType.Yoyo);
_canvasGroup.DOFade(0f, 0.5f).OnComplete(() => gameObject.SetActive(false));
// Sequences
DOTween.Sequence()
.Append(transform.DOMove(pos1, 0.5f))
.Append(transform.DOMove(pos2, 0.5f))
.Join(transform.DORotate(new Vector3(0, 180, 0), 0.5f));
Use DOTween for UI animations, camera effects, and any animation that needs to be driven by game logic rather than pre-authored clips.
Timeline¶
Timeline is for cinematic sequences, cutscenes, and scripted events:
- Activation Track: enable/disable GameObjects at specific times
- Animation Track: play animation clips on specific objects
- Audio Track: trigger audio clips with precise timing
- Signal Track: fire events at specific points in the timeline
- Cinemachine Track: control camera shots and transitions
Control playback from code:
[SerializeField] private PlayableDirector _director;
public void PlayCutscene()
{
_director.Play();
}
public void SkipCutscene()
{
_director.time = _director.duration;
_director.Evaluate();
}
2D Sprite Animation¶
For 2D games, animate sprites using the Animator:
- Import a sprite sheet and set Sprite Mode to "Multiple"
- Use the Sprite Editor to slice individual frames
- Create an Animation Clip by dragging frames into the Animation window
- The Animator Controller manages state transitions between clips
Use SpriteRenderer.flipX for direction changes instead of duplicating animations.