Locomotion

This page is part of the 3D Game Kit example

The character has several animations that can be blended to allow movement at any speed as well as to turn quickly when needed.

Mecanim

The Mecanim character's LocomotionSM state is a Sub State Machine containing a main Locomotion Blend Tree to allow for movement at any speed, left and right quick turn animations, and the Idle state mentioned on the Idle page:

Animancer

With Animancer, all the state logic is defined in the LocomotionState script which handles everything that applies while the character is moving along the ground except for things that also apply in other states as well (such as the Creature.OnAnimatorMove method described on the Movement page):

using Animancer;
using System;
using UnityEngine;

public sealed class LocomotionState : CreatureState
{
    [SerializeField] private Float2ControllerState.Transition _LocomotionBlendTree;
    [SerializeField] private ClipState.Transition _QuickTurnLeft;
    [SerializeField] private ClipState.Transition _QuickTurnRight;
    [SerializeField] private float _QuickTurnMoveSpeed = 2;
    [SerializeField] private float _QuickTurnAngle = 145;

    private void Awake()
    {
        _QuickTurnLeft.Events.Sequence.OnEnd =
            _QuickTurnRight.Events.Sequence.OnEnd =
            () => Creature.Animancer.Play(_LocomotionBlendTree);
    }

    public override bool CanEnterState(CreatureState previousState)
    {
        return Creature.CharacterController.isGrounded;
    }

    private void OnEnable()
    {
        Creature.Animancer.Play(_LocomotionBlendTree);
    }

    private void FixedUpdate()
    {
        if (Creature.CheckMotionState())
            return;

        Creature.UpdateSpeedControl();
        _LocomotionBlendTree.State.ParameterX = Creature.ForwardSpeed;

        UpdateRotation();
        UpdateAudio();
    }

    private void UpdateRotation()
    {
        if (!_LocomotionBlendTree.State.IsActive)
            return;

        float currentAngle, targetAngle;
        if (!Creature.GetTurnAngles(Creature.Brain.Movement, out currentAngle, out targetAngle))
            return;

        if (Creature.ForwardSpeed > _QuickTurnMoveSpeed)
        {
            var deltaAngle = Mathf.DeltaAngle(currentAngle, targetAngle);
            if (Mathf.Abs(deltaAngle) > _QuickTurnAngle)
            {
                var turn = deltaAngle < 0 ? _QuickTurnLeft : _QuickTurnRight;

                if (turn.State == null || turn.State.Weight == 0)
                {
                    Creature.Animancer.Play(turn);
                    return;
                }
            }
        }

        Creature.TurnTowards(currentAngle, targetAngle, Creature.CurrentTurnSpeed);
    }

    [SerializeField] private UnityEvent _PlayFootstepAudio;
    private bool _CanPlayAudio;
    private bool _IsPlayingAudio;

    private void UpdateAudio()
    {
        var footFallCurve = _LocomotionBlendTree.State.ParameterY;

        if (footFallCurve > 0.01f && !_IsPlayingAudio && _CanPlayAudio)
        {
            _IsPlayingAudio = true;
            _CanPlayAudio = false;
            _PlayFootstepAudio.Invoke();
        }
        else if (_IsPlayingAudio)
        {
            _IsPlayingAudio = false;
        }
        else if (footFallCurve < 0.01f && !_CanPlayAudio)
        {
            _CanPlayAudio = true;
        }
    }
}

Movement Moving the character's position.
Turning Turning the character's rotation.