UnityのNavMeshを使ってみる

こんにちは。ヤマヤタケシです。

バレンタインデーを引きこもってやりすごしました。
危ない、危ない。

さて突然ですが。
ゲームでよくある障害物を避けて目的地にたどり着くってのは予想以上に難しぃぃ!

しかし、なんと!
そんなイチから実装すると難しい機能が、Unityにナビメッシュとして入っているらしいじゃないですか!

マニュアル→ナビゲーションと経路探索

やってみた結果、こんな感じッス。
壁を避けて目的地へ行くでしょ?

さて、習うより慣れろということで、やってみます。

Unity5.3.2を起動します。
まだ何も置いてません。
001

地面と壁に相当するキューブを置きました。せっかくなのでマテリアルも設定します。なんのライトも設定していないのに、柔らかい光がきれいです。
002

わかりやすいようにBGRootの下に地面と壁のキューブをぶら下げてあります。
他の皆さんはどうやってるかは知らないですけど、種類別にツリーにすると便利です。
こんな感じでBGRootを選んで、「Navigation Static」にします。
003

そして、Window -> Navigation を選びます。
005

Navigationのウインドウが出てきました!
タブのObjectからBakeに切り替えます。
設定はとりあえず触らずに下にある「Bake」ボタンを押します。
006

ばーん!
それっぽい画面になりました!
凸なメッシュに分割されました!
スゲー!
一瞬!
007

移動するオブジェクトを追加します。今回、選ばれたのはシリンダさんです。
008

このシリンダさんに Nav Mesh Agent を追加します。
009

行き先のゴールをキューブで置きます。別にキューブじゃなくてもTransformが取れれば何でもOK!
010

そして、スクリプトを書きます。
「NavMeshAgentを取得して、ゴールを設定。」するだけです。
なんということでしょう。こんなに少ないコードで動作するとは。

//
// ナビゲーションのテスト
//
using UnityEngine;
using System.Collections;

public class NaviAgent : MonoBehaviour
{
    public Transform goal;
    Vector3 start;

    // Use this for initialization
    void Start () {
        // 最初の位置を覚えておく
        start = transform.position;
        // NavMeshAgentを取得して
        var agent = GetComponent<NavMeshAgent>();

        // ゴールを設定。
        agent.destination = goal.position; 
    }
    
    // Update is called once per frame
    void Update () {
        // クリックで最初の位置にもどる。
        if( Input.GetMouseButtonDown(0) ) {
            transform.position = start;
        }
    }
}

シリンダさんにこのスクリプトを追加します。
011
最後に!
スクリプトに追加したpublicなGoalにゴールにさっきのゴールなキューブを関連付けます。
引っ張って、ポイ!
012

どきどき、しながら、再生ボタンを押すと!
動いたー!

そんじゃまた。