
オフメッシュリンク上でのアニメーションや速度を変えるの歩行アニメーションをブレンドツリーで揃えてみました。
ブレンドツリーを作る
まず、アニメーターコントローラーで新しいブレンドツリーの設定されたステートを作りました。

このステートを右クリックして「Set as Layer Default State」を選択して、デフォルトステートにします。

ブレンドツリーでは、+ボタンを2回クリックしてモーションをアタッチする欄を2つ作りました。また、ブレンドツリーを作るとモーションをブレンドするためのFloat型のパラメーターが作られています。


この欄に2種類の歩行モーションをドラッグアンドドロップします。赤いシークバーを動かすと、プレビューでブレンドされる様子が見れます。

パラメーターの値が0のときは1つ目、1のときは2つ目のアニメーションだけになって、その中間では値に応じてブレンドされます。

このステートでは2歩分の歩行モーションを繰り返します。足が揃わないときは、インポート設定のAnimationタブの「Cycle Offset」でループの開始位置を補正できます。

スクリプト
スクリプトで、このパラメーターの値をセットします。
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(Animator))]
public class OffMeshLinkTest : MonoBehaviour
{
    NavMeshAgent agent;
    Animator animator;
    bool isPassing;
    bool isBlending;
    [SerializeField] Transform goal;
    float defaultSpeed;
    [SerializeField] float linkSpeed = 0.2f;
    [SerializeField] float blendSpeed = 0.1f;
    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.autoTraverseOffMeshLink = true;
        // 目的地を設定
        agent.destination = goal.position;
        // スピードを保存
        defaultSpeed = agent.speed;
        animator = GetComponent<Animator>();
    }
    // Update is called once per frame
    void Update()
    {
        // 通過中
        if(isPassing)
        {
            // オフメッシュリンクから抜けると
            if (!agent.isOnOffMeshLink)
            {
                // スピードを戻す
                agent.speed = defaultSpeed;
                
                // 通過中を解除
                isPassing = false;
                isBlending = true;
            }
            // オフメッシュリンク上でブレンド中のとき
            else if (isBlending)
            {
                // パラメーターを1に向けて上げる
                animator.SetFloat("Blend", 1f, blendSpeed, Time.deltaTime);
                // 0.9以上のとき
                if (animator.GetFloat("Blend") >= 0.9f)
                {
                    animator.SetFloat("Blend", 1f);
                    // ブレンド中を解除
                    isBlending = false;
                }
            }
        }
        // 通過中でないとき
        else
        {
            // オフメッシュリンク上に来たら
            if(agent.isOnOffMeshLink)
            {
                // スピードを遅くする
                agent.speed = defaultSpeed * linkSpeed;
                // 通過中にする
                isPassing = true;
                // ブレンド中にする
                isBlending = true;
            }
            // オフメッシュリンク上でなくブレンド中のとき
            else if (isBlending)
            {
                // パラメーターの値を0に向かって下げる
                animator.SetFloat("Blend", 0f, blendSpeed, Time.deltaTime);
                // 0.1以下になると
                if (animator.GetFloat("Blend") <= 0.1f)
                {
                    animator.SetFloat("Blend", 0f);
                    // ブレンド中を解除
                    isBlending = false;
                }
            }
        }
    }
}
値の設定にはAnimator.SetFloatメソッドを使います。第一引数でパラメーターを指定して、第二引数に目的の値を渡します。引数が4つのオーバーロードでは、第三引数に渡す値によって、目的の値になるまでにかかる時間を調整できます。
// パラメーターを1に向けて上げる
animator.SetFloat("Blend", 1f, blendSpeed, Time.deltaTime);
// 0.9以上のとき
if (animator.GetFloat("Blend") >= 0.9f)
{
    animator.SetFloat("Blend", 1f);
    // ブレンド中を解除
    isBlending = false;
}これで、歩行の周期が揃いました。


目的の値の付近で変化が鈍くなって到達しきらないので、その手前で目的の値に切り替えています。


