ナビメッシュで巡回中に停止させてアニメーションさせる

投稿者: | 2020-04-01


ナビメッシュエージェントに巡回させて、目的地に付いた時に一旦巡回を停止させて、その場でアニメーションさせてみました。

NPCにスクリプトを付けて、ベンチと2つの目的地をアタッチしています。

目的地は空のゲームオブジェクトで、少し離れたところと、ベンチの前に置きます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AgentScript : MonoBehaviour
{
    public Transform[] point;
    public Transform bench;
    NavMeshAgent agent;
    Animator animator;

    int n = 0;

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        animator = GetComponent<Animator>();

        agent.destination = point[0].position;
    }

    // Update is called once per frame
    void Update()
    {
        // 目的地に近づいたら
        if (!agent.pathPending && agent.remainingDistance < 0.5f)
        {

            if (n == 0) n = 1;
            else n = 0;


            // ベンチの前に来たとき
            if (n == 0)
            {
                agent.speed = 0f; // エージェントの動きを止める
                animator.SetInteger("param1",1); // 座るアニメーションに遷移させる
                agent.updateRotation = false; // 回転を止める

                // ベンチにまっすぐ座るために回転させる
                Quaternion q = Quaternion.FromToRotation(transform.forward, bench.forward);
                transform.Rotate(q.eulerAngles);

                agent.Warp(point[1].position); // ベンチの前にワープ

            }


            agent.destination = point[n].position; 

        }


        if (animator.GetAnimatorTransitionInfo(0).IsName("Sitdown -> Walk"))
        {
            animator.SetInteger("param1", 0);
            agent.updateRotation = true; // 回転を再開
            agent.speed = 5f;

        }

    }

}

デフォルトが歩くアニメーションで、Int型のparam1が1になると、座るアニメーションに遷移します。

座るアニメーションが終わると自動的に歩くアニメーションに戻ります。

エージェントがベンチの前に来ると、speedを0にしてエージェントの動きを止めます。そのままではエージェントは座るアニメーションをしたまま目的地の方を向いてしまうので、agent.updateRotation = false; でエージェントの回転を止めています。

座る位置がずれないように、目的地の上にワープさせています。

NPCをベンチにまっすぐ座らせる



FromToRotationメソッドを使うと、第一引数の方向から第二引数の方向へ向かせるための回転値が得られます。

Quaternion q = Quaternion.FromToRotation(transform.forward, bench.forward);
エージェントの正面の方向とベンチの正面の方向を入れています。

この回転をエージェントに加えます。
transform.Rotate(q.eulerAngles);

アニメーターの遷移中の処理<

アニメーターのGetAnimatorTransitionInfoを使って遷移中の処理を書きます。

if (animator.GetAnimatorTransitionInfo(0).IsName("Sitdown -> Walk"))
{
    animator.SetInteger("param1", 0); // パラメーターを0に戻す
    agent.updateRotation = true; // 回転を再開
    agent.speed = 5f;
}

遷移の矢印のインスペクタで、「Transition Duration」が0になっているとGetAnimatorTransitionInfoは実行されないので、ここには0より大きい値を入れておきます。


IsNameでなく、IsUserNameを使うとこのインスペクタの空欄に入れた任意の名前を使えます。

ベンチに座る時にキャラクターが浮く

はじめはベンチに座る時にキャラクターが浮いてしまいました。


インポート設定のアニメーションタブで、Root Transform Position (Y) のBake Into Poseにチェックを入れると解決しました。


コメントを残す

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