Outlook Respawn LogoOutlook Respawn Logo
Young creative 3D designer creates video game character or animations and works remotely at home office

Animation in Unity: From Mecanim Basics to Blend Trees

Animation in Unity: From Mecanim Basics to Blend Trees

Unity animation from scratch: Mecanim, blend trees, root motion, animation events, and foot IK.

25 MAY 2026, 07:59 PM

Highlights

  • Unity Mecanim supports blend trees, animation events, root motion, and Humanoid IK for advanced locomotion.
  • Proper Mixamo and Blender import settings prevent retargeting, rotation, and root motion issues.
  • Foot IK raycasts align characters naturally to slopes and uneven terrain at runtime.

Most Unity developers can get a character moving. Few can get one moving well. The gap between those two outcomes lives almost entirely inside the animation pipeline. Tools like Mecanim, root motion control, blend trees, animation events, and inverse kinematics are all native to Unity and widely misunderstood.

This Unity animation tutorial builds a character locomotion project from scratch. It covers importing rigs from Mixamo and Blender, wiring the Unity Animator, constructing blend trees for movement, choosing between root motion and in-place animation, firing events at hit frames, and grounding the character with basic foot inverse kinematics (IK).

Setting Up the Asset Pipeline: Mixamo and Blender Imports

Before the Unity Animator touches anything, it needs clips. Mixamo is the fastest on-ramp available.

Start by downloading the base character with skin included, selecting a humanoid rig such as Y-Bot, and exporting it as FBX for Unity. This first download must include the skin because Unity needs a valid skeleton to build the Avatar and perform retargeting correctly. Downloading with skin also prevents duplicate meshes from cluttering the project as more animations are added.

All subsequent locomotion animations, such as walk and run cycles, can then be downloaded separately with the skin excluded, which keeps file sizes down significantly.

For the "In Place" setting, the choice depends on how you plan to move the character. Ticking "In Place" removes positional displacement from the clip, meaning forward momentum is stripped out and movement control passes entirely to your CharacterController or NavMesh script. Leaving it unchecked enables root motion, where the animation physically propels the character through the scene. Both approaches are valid and covered in more detail in the root motion section below.

Inside Unity, select each FBX. Under the Rig tab in the Inspector, set Animation Type to Humanoid and click Apply. For the base character, set the Avatar Definition to "Create From This Model."

For every animation-only FBX, set it to "Copy From Other Avatar" and point it at the base character. This retargeting approach is a recognized best practice because it establishes a consistent bone mapping hierarchy across all clips and prevents runtime errors.

Under the Animation tab, enable Loop Time for all locomotion clips so cycles play without interruption. To prevent the character from drifting during a loop, tick Bake Into Pose under Root Transform Position. Additionally, set Based Upon to Body Orientation under Root Transform Rotation and keep Offset at its original value. These two settings together lock the character's root position locally and remove any off-center drift that can appear mid-cycle.

For Blender exports, the axis alignment must match Unity's coordinate system precisely. Set the Forward axis to Z Forward and the Up axis to Y Up. Under the armature export options, set Primary Bone Axis to X Axis and Secondary Bone Axis to Y Axis, which ensures Mixamo skeletons import without rotation issues. Disable Add Leaf Bones to prevent Unity from generating extra redundant joints.

For animation-only FBX files, enable Bake Animation, activate only the relevant action, and check Only Deform Bones to reduce the joint count and keep the file clean.

A clean folder structure prevents asset management problems as the project grows. The recommended layout separates meshes from logic across four folders: Assets/Characters/ for base meshes and materials, Assets/Animations/ for raw FBX files and imported clips, Assets/Animators/ for Animator Controllers and Avatar Masks, and Assets/Scripts/ for movement and gameplay logic.

This separation scales cleanly as the project expands.

How to Build the Unity Animator Controller With States and Transitions

The Animator Controller is a state machine (SM). Each state holds a clip or a blend tree. Transitions between states are governed by parameters, booleans, floats, integers, and triggers that scripts update at runtime.

To build the locomotion controller:

  1. Right-click inside Assets/Animators/, select Create, then Animator Controller, and name it CharacterLocomotion.
  2. Inside the Animator window, create an Idle state assigned to the idle clip and a Locomotion state that will hold the blend tree.
  3. Add a Float parameter named Speed.
  4. Set the Idle to Locomotion transition condition to Speed greater than 0.1 with Has Exit Time unchecked, and reverse the condition for the return transition.
  5. Assign this controller to the Animator component on the character GameObject.

Unity Blend Trees: Driving Smooth Movement with 1D and 2D Blending

Blend trees are where Unity animation shifts from functional to fluid. As Unity's official documentation states, a blend tree allows multiple animations to be blended smoothly by incorporating parts of them all to varying degrees. The blend trees Unity developers build for locomotion eliminate the transition latency and visible pop that come from standard state-to-state switching.

1D Blend Tree for Walk and Run

  1. Double-click the Locomotion state and select Create Blend Tree in State.
  2. Set Blend Type to 1D and the parameter to Speed.
  3. Add the Idle clip at threshold 0 first; without it, a Speed value anywhere above zero but below the Walk threshold will produce a half-walk while the character is standing still.
  4. Add the Walk clip at threshold 0.5 and the Run clip at threshold 1.0. Unity interpolates bone transforms between these values continuously as Speed changes, producing a seamless idle-to-walk-to-run transition driven by a single float.

2D Blend Tree for Directional Movement

  1. Set Blend Type to 2D Simple Directional.
  2. Add two float parameters: VelocityX and VelocityZ.
  3. Populate motion fields for Idle at (0, 0), Walk Forward at (0, 0.5), Run Forward at (0, 1.0), Walk Left at (-0.5, 0 ), Walk Right at (0.5, 0), and Walk Backward at (0, -0.5). Note that the backward threshold must be entered as a negative float value (-0.5) in the editor. Unity calculates a weighted average of surrounding clips based on where the velocity vector sits on the 2D field in real time.

Drive these parameters from a script using damped SetFloat calls. The damp time argument of 0.1f prevents the snapping between blend positions that causes robotic-feeling locomotion.

Passing Time.deltaTime as the fourth argument in Animator.SetFloat(name, value, dampTime, deltaTime) lets Unity handle frame-rate independence internally; no manual delta time multiplication is needed on the value itself.

Root Motion or In-Place Animation: Which Approach is Right for Your Project?

Root motion moves the physical GameObject transform directly through the animation clip. In-place animation keeps the transform at its origin while a CharacterController or Rigidbody script handles all velocity calculations independently.

Root motion suits committed, authored movement where physical displacement must be perfectly timed to the visual: a vaulting sequence, a lunge attack, or a jump where the arc needs to match the collider precisely. In-place animation suits player-controlled WASD locomotion, where code dictates velocity and the animation serves as a visual overlay on top of that movement.

The general rule is straightforward. For code-driven locomotion, leave Apply Root Motion unchecked on the Animator component and let your CharacterController or Rigidbody script handle all velocity and displacement. For animation-driven root motion, check Apply Root Motion on the Animator and leave Bake Into Pose unchecked so the clip physically drives the transform.

For this project, leave Apply Root Motion unchecked on the Animator component, and ensure your CharacterController or Rigidbody script is fully handling velocity based on player input. Download Mixamo clips with the "In Place" option ticked, or configure the imported FBX manually inside Unity using the steps below.

To configure an existing clip for script-driven locomotion inside Unity without re-exporting, follow these steps:

  1. Select the FBX file in the Project window and open the Animation tab, then select the specific clip you want to configure.
  2. Scroll to Root Transform Position (XZ) and tick Bake Into Pose. Set Based Upon to Original or Center of Mass. Baking XZ into the pose locks horizontal movement to the animation's origin, preventing the visual mesh from walking away from the GameObject's collider while your script handles the actual displacement.
  3. Scroll to Root Transform Position (Y) and tick Bake Into Pose. For the Based Upon value, prefer Feet over Original. Feet anchors the root to the floor level of the character, which prevents subtle vertical jitter on locomotion clips where the FBX author didn't perfectly zero out the pivot at floor level. Original is acceptable if your pivot is clean, but Feet is the safer default.
  4. Scroll to Root Transform Rotation and tick Bake Into Pose. Set Based Upon to Original or Body Orientation. This prevents the animation from rotating the GameObject, allowing your movement or mouse-look script to handle turning without the Animator overriding it.
  5. Click Apply at the bottom of the Inspector.

One important note: ‘averageSpeed: animator.velocity’ returns the root motion delta computed from the current animation frame and remains readable at runtime regardless of whether Apply Root Motion is enabled or disabled. Disabling Apply Root Motion stops the engine from automatically moving the transform with that data, but does not stop the computation itself. ‘AnimationClip.averageSpeed’ is a separate, pre-computed clip-level value useful for calibrating blend tree speed thresholds or scaling input velocity to match the animation's cadence.

Use ‘animator.velocity’ for per-frame runtime speed and ‘AnimationClip.averageSpeed’ for clip-level configuration.

One important note on ‘OnAnimatorMove()’: if this callback is declared on a script attached to the same GameObject, Unity assumes you want to manually process and apply the animation's motion yourself. Leaving it empty will cause the character's movement to stop entirely because the engine is waiting for your code to tell it where to move.

If you are using standard script-driven movement via a CharacterController or Rigidbody, do not implement ‘OnAnimatorMove()’ at all.

Animation Events for Hit Frames: Precision Timing at the Frame Level

Animation events fire C# methods at exact frames, making them the standard technique for activating hitboxes, triggering audio, or spawning particles at the precise moment contact visually occurs in an attack animation.

Select the animation FBX in the Project window, open the Animation tab, move the preview playhead to the target hit frame, and click Add Event. Type the method name in the Function field, for example, ‘OnHitFrame.’ Any script attached to the same GameObject that holds the Animator component containing a method with that exact name will execute when that marker is crossed during playback.

A mismatch between the event name and the script method produces a console warning, and the event will not fire, but the game will continue running. Two common causes are a spelling mismatch and accidentally including parentheses in the Function field. Use ‘OnHitFrame,’ not ‘OnHitFrame().’ The receiving method must also be defined with either zero parameters or exactly one parameter of type ‘string,' 'float,' 'int,' or 'AnimationEvent.'

One practical note on working with FBX files: animation clips inside an imported FBX are read-only, so events added directly in the Animation tab may not persist or may be uneditable. To extract an editable copy, expand the FBX in the Project window by clicking the arrow beside it, select the target clip, and press Ctrl+D to save a standalone .anim file. Add your events to that duplicate and reference it in your Animator Controller, keeping your rig settings tied to the original FBX.

If you have multiple attack variants, an AnimatorOverrideController is worth considering as an alternative, as it lets you reuse a single Animator Controller structure by swapping clips per character or context at runtime. Each replacement clip will still need its own events defined, since events are stored on the clip asset rather than the Animator state.

IK for Foot Placement: Grounding Characters on Uneven Terrain

The built-in Humanoid IK system in Mecanim adjusts foot positions procedurally against real geometry at runtime. ‘OnAnimatorIK’ and the associated IK functions only operate on Humanoid rigs. Enable IK Pass in the Animator Controller layer settings, then implement the ‘OnAnimatorIK’ callback in a script on the same GameObject as the Animator.

Assign the Animator reference in ‘Awake()’ and cast rays downward from each foot to reposition them against the surface below.

For rotation, retrieve the current animated foot rotation via the ‘animator.GetIKRotation,’ compute a tilt from world up to the surface normal using ‘Quaternion.FromToRotation(Vector3.up, hit.normal)’, and multiply it against the animated foot rotation. This conforms the foot to the slope while preserving the animated ankle pose.

The LookRotation approach requires the forward and up vectors to be perfectly perpendicular, which is not guaranteed when deriving the forward direction from a cross product against an arbitrary animated rotation, and can cause the foot to twist or pop on steep terrain:

Csharp

using UnityEngine;

public class FootIKController : MonoBehaviour

{

    [SerializeField] private Animator animator;

    [SerializeField] private LayerMask groundLayer;

    [SerializeField] private float footOffset = 0.05f;

    [SerializeField] private float rayDistance = 1.5f;

    [Range(0f, 1f)]

    [SerializeField] private float ikWeight = 1.0f;

    private void Awake()

    {

        if (!animator) animator = GetComponent<Animator>();

    }

    private void OnAnimatorIK(int layerIndex)

    {

        if (!animator) return;

        animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, ikWeight);

        animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, ikWeight);

        animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, ikWeight);

        animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, ikWeight);

        HandleFootIK(AvatarIKGoal.LeftFoot);

        HandleFootIK(AvatarIKGoal.RightFoot);

    }

    private void HandleFootIK(AvatarIKGoal foot)

    {

        Vector3 footPos = animator.GetIKPosition(foot);

        Vector3 rayOrigin = footPos + Vector3.up * 1.0f;

        if (Physics.Raycast(rayOrigin, Vector3.down, out RaycastHit hit, rayDistance + 1.0f, groundLayer))

        {

            Vector3 targetPos = hit.point;

            targetPos.y += footOffset;

            animator.SetIKPosition(foot, targetPos);

            Quaternion tilt = Quaternion.FromToRotation(Vector3.up, hit.normal);

            animator.SetIKRotation(foot, tilt * animator.GetIKRotation(foot));

        }

    }

}

Note: Excludes pelvis adjustment, per-frame weight blending, and non-standard gravity support.

The ray origin sits 1.0f above the animated foot position, and the cast distance is extended by the same amount, ensuring ledges and steep descents are detected reliably. Note that ‘animator.GetIKPosition’ returns world space coordinates. If the character is on a rotating platform or operating under non-standard gravity, the ray direction and origin should account for the surface's actual up vector rather than assuming ‘Vector3.down’ and ‘Vector3.up’ are valid.

Three additional considerations are worth addressing before taking this to production.

First, adjusting foot position alone can cause the legs to overstretch when the ground drops away sharply. The standard fix is to raycast from the character's center and lower the pelvis via ‘animator.bodyPosition’ so the legs retain enough reach to touch the surface.

Second, ‘ikWeight’ should be driven by an Animation Curve tied to the walk cycle rather than held at a constant value, blending to 1.0 when the foot is grounded and 0.0 when it is lifting, so the IK does not fight the step-up phase of the animation. The result is a character whose feet conform to slopes and steps without any additional animation authoring.

For more complex procedural rigs, multi-limb constraints, aim solvers, and two-bone IK chains, Unity's Animation Rigging package extends Mecanim without replacing it. Unlike the built-in Humanoid IK system, it works on both Humanoid and Generic rig types, making it suitable for any biped or creature setup.

The package has been available through the Package Manager since Unity 2019.1.

The Completed Locomotion Project

The finished scene uses one Y-Bot mesh, five Mixamo clips imported without skin, the CharacterLocomotion Animator Controller with a 2D blend tree, and a LocomotionController script driving VelocityX and VelocityZ. A FootIK script corrects foot placement against a plane collider.

Scene complexity stays low. The pipeline does the work.

This foundation scales directly into production systems. Avatar Masks add upper-body weapon or gesture layers without disturbing the locomotion blend tree underneath. Timeline reuses the same Animator for cutscenes. The blend trees Unity developers build in a locomotion demo are structurally identical to those in shipped commercial titles; the production version simply carries more states and finer parameter tuning.

Every system here ships with Unity at no additional cost and represents the pipeline baseline that professional Unity animation engineers are expected to know before entering a studio role.

Probaho Santra is a content writer at Outlook India with a master’s degree in journalism. Outside work, he enjoys photography, exploring new tech trends, and staying connected with the esports world.

Published At: 25 MAY 2026, 07:59 PM
Tags:Careers