【Unity】オフメッシュリンク上でのアニメーションや速度を変える #2

投稿者: | 2021-08-07

オフメッシュリンク上でのアニメーションや速度を変えるの歩行アニメーションをブレンドツリーで揃えてみました。

ブレンドツリーを作る

まず、アニメーターコントローラーで新しいブレンドツリーの設定されたステートを作りました。

このステートを右クリックして「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;
}

これで、歩行の周期が揃いました。

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

コメントを残す

メールアドレスが公開されることはありません。