9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

2DでNavMeshを実装する方法-初心者に優しく-

Posted at

0.完成像

見にくいかもしれないですが、こんな感じで障害物をよけてプレイヤー(このGIFの勇者のスプライト)を追跡する敵(このGIFのおばけのスプライト)を作りたいと思います。もう少し詳しく言うと、2DのUnityゲームでTilemap(タイルマップ)をもとにNavMeshを実装する、というものです。
test2d-test2-PC_-Mac--Linux-Standalone-Unity-2020.3.21f1-Personal-DX11-2022-02-11-20-43-15_Trim.gif

1.【注意点】NavMeshについて

この記事を見ている皆さんはきっと、「NavMeshって2Dでは実装できないのかなー」という感じの人が大半じゃないかと思っています。3DでNavMesh自体は触ったことがあって、それありきで2Dでも、という人ですね。

もしご存じない方は、一度3DでNavMeshを軽く触ってから、この記事を読まれることをおすすめします。なぜなら、NavMeshの2Dバージョンは正規のUnityエディタだけでは実装できないからです。そんな応用編をやる前に、まずは普通に3DでNavMeshを扱って前提知識をインプットしておきましょう。

2.NavMesh2Dの拡張

まずはここにアクセス。

Unityテクノロジー公式から、2DバージョンのNavMeshが作成されているので、これをダウンロードします。

qiita1.png

ZIP形式でダウンロードしたら、即解凍。
解凍後のフォルダを、NavMeshComponents-2019.3-2D→NavMeshComponents-2019.3-2D→Assets→…と辿り、下の画像のような画面に到達したら、指定のフォルダをUnityのプロジェクトのAssets下にインポートします。

qiita2.png

3.Tilemapの作成

2DのNavMeshはTilemapを前提にするものなので、まずはTilemapを作成しましょう。
TilemapはUnityの2Dの基本かと思いますので、この記事ではそれが完成した前提で進めていきます

設定面で必要な工程としては、Tile(タイル)の設定になります。
NavMeshの障害物となるTileに関しては、Collider TypeをNoneに変更します。

qiita3.png

Tileの一部だけ障害物にしたい場合は、Sprite EditorのCustom Physics Shapeで調整できます。
気になる人はググってみてください。

4.NavMeshの形成

ではでは、本題のNavMeshを形成していきましょう。

1.Unityエディタ左上メニューからWindows→AI→Navigationと進んでNavigationウィンドウを出す。NavigationウィンドウをAgent→Radiusと進み、Radiusの項目を小さい値に設定する。(所感としては0.05あたりがいいのでは、と思っている。個人差あり)

qiita4.png

2.ヒエラルキー上の Tilemap を選択、Tilemap Colider 2DNav Mesh Source Tag 2D のコンポーネントを追加する

qiita5.png

3.適当に空オブジェクトでも作って、そこにNav Mesh Builder 2Dのコンポーネントを追加する。追加後、Bakeのボタンを押す。

qiita6.png

4.NavigationウィンドウとSceneビューを並べてみよう。Sceneビューで、NavMeshが青く形成されているのがわかるはず…!

qiita7.png

5.しっかりBakeできているな、と思ったら、最後にNav Mesh Builder 2DのコンポーネントのBake On Enableの項目にチェックをいれよう。ここを忘れがち!

qiita8.png

5.NavMeshAgent2D

さて、NavMeshまで形成できたらあとはNavMeshAgentをつけて…!と、いきたいところですが、なんとNavMeshAgentは2Dに対応していません。

なので、2D版のNavMeshAgentを簡単に作っておきました。
こちらのスクリプトになります。

NavMeshAgent2D.cs
using UnityEngine;
using UnityEngine.AI;

public class NavMeshAgent2D : MonoBehaviour
{
    [Header("Steering")]
    public float speed = 1.0f;
    public float stoppingDistance = 0;

    [HideInInspector]//常にUnityエディタから非表示
    private Vector2 trace_area=Vector2.zero;
    public Vector2 destination
    {
        get { return trace_area; }
        set
        {
            trace_area = value;
            Trace(transform.position, value);
        }
    }
    public bool SetDestination(Vector2 target)
    {
        destination = target;
        return true;
    }

    private void Trace(Vector2 current,Vector2 target)
    {
        if (Vector2.Distance(current,target) <= stoppingDistance)
        {
            return;
        }

        // NavMesh に応じて経路を求める
        NavMeshPath path = new NavMeshPath();
        NavMesh.CalculatePath(current, target, NavMesh.AllAreas, path);

        Vector2 corner = path.corners[0];

        if (Vector2.Distance(current, corner) <= 0.05f)
        {
            corner = path.corners[1];
        }

        transform.position = Vector2.MoveTowards(current, corner, speed * Time.deltaTime);
    }
}

NavMeshAgent2D という名前のスクリプトを作成して、あとは上記のスクリプトをコピペしてください。

6.NavMeshAgent2Dの使い方

NavMeshAgent2D は、本物のNavMeshAgentの機能のほんの一部のみを実装したスクリプトですが、使用法としてはNavMeshAgentと同様に使用していただけます。

1.NavMeshを適用したい物体(今回だと敵キャラのおばけ)にNavMeshAgent2Dをアタッチする
2.敵キャラのスクリプトでNavMeshを利用した挙動を実装する

サンプルのスクリプトとしたら、こんな感じでしょうか。

FollowPlayer.cs
using UnityEngine;

public class FollowPlayer : MonoBehaviour
{
    NavMeshAgent2D agent; //NavMeshAgent2Dを使用するための変数
    [SerializeField] Transform target; //追跡するターゲット

    void Start()
    {
        agent = GetComponent<NavMeshAgent2D>(); //agentにNavMeshAgent2Dを取得
    }

    void Update()
    {
        agent.destination = target.position; //agentの目的地をtargetの座標にする
		//agent.SetDestination(target.position); //こっちの書き方でもオッケー
    }
}

7.最後に

最近購入した『Unityプログラミング・バイブル2nd』という書籍によると、「ナビゲーションシステムは、Unityの機能のなかでも枯れた機能となりつつ」あるらしいです。不具合などが少ない反面、近年は大きな機能追加や修正はされていないそうです。
おそらくこの2D版NavMeshも、公式採用されることはないんだろうなぁと思ったり。

現状、上記のNavMeshAgent2Dは主に追跡しかできませんが、暇なときにほかの機能も追加していこうと思います。
ここまで読んでいただきありがとうございました。

以上

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?