Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9738

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

$
0
0
0.完成像 見にくいかもしれないですが、こんな感じで障害物をよけてプレイヤー(このGIFの勇者のスプライト)を追跡する敵(このGIFのおばけのスプライト)を作りたいと思います。もう少し詳しく言うと、2DのUnityゲームでTilemap(タイルマップ)をもとにNavMeshを実装する、というものです。 1.【注意点】NavMeshについて この記事を見ている皆さんはきっと、「NavMeshって2Dでは実装できないのかなー」という感じの人が大半じゃないかと思っています。3DでNavMesh自体は触ったことがあって、それありきで2Dでも、という人ですね。 もしご存じない方は、一度3DでNavMeshを軽く触ってから、この記事を読まれることをおすすめします。なぜなら、NavMeshの2Dバージョンは正規のUnityエディタだけでは実装できないからです。そんな応用編をやる前に、まずは普通に3DでNavMeshを扱って前提知識をインプットしておきましょう。 2.NavMesh2Dの拡張 まずはここにアクセス。 Unityテクノロジー公式から、2DバージョンのNavMeshが作成されているので、これをダウンロードします。 ZIP形式でダウンロードしたら、即解凍。 解凍後のフォルダを、NavMeshComponents-2019.3-2D→NavMeshComponents-2019.3-2D→Assets→…と辿り、下の画像のような画面に到達したら、指定のフォルダをUnityのプロジェクトのAssets下にインポートします。 3.Tilemapの作成 2DのNavMeshはTilemapを前提にするものなので、まずはTilemapを作成しましょう。 TilemapはUnityの2Dの基本かと思いますので、この記事ではそれが完成した前提で進めていきます 設定面で必要な工程としては、Tile(タイル)の設定になります。 NavMeshの障害物となるTileに関しては、Collider TypeをNoneに変更します。 Tileの一部だけ障害物にしたい場合は、Sprite EditorのCustom Physics Shapeで調整できます。 気になる人はググってみてください。 4.NavMeshの形成 ではでは、本題のNavMeshを形成していきましょう。 1.Unityエディタ左上メニューからWindows→AI→Navigationと進んでNavigationウィンドウを出す。NavigationウィンドウをAgent→Radiusと進み、Radiusの項目を小さい値に設定する。(所感としては0.05あたりがいいのでは、と思っている。個人差あり) 2.ヒエラルキー上の Tilemap を選択、Tilemap Colider 2D と Nav Mesh Source Tag 2D のコンポーネントを追加する 3.適当に空オブジェクトでも作って、そこにNav Mesh Builder 2Dのコンポーネントを追加する。追加後、Bakeのボタンを押す。 4.NavigationウィンドウとSceneビューを並べてみよう。Sceneビューで、NavMeshが青く形成されているのがわかるはず…! 5.しっかりBakeできているな、と思ったら、最後にNav Mesh Builder 2DのコンポーネントのBake On Enableの項目にチェックをいれよう。ここを忘れがち! 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は主に追跡しかできませんが、暇なときにほかの機能も追加していこうと思います。 ここまで読んでいただきありがとうございました。 以上

Viewing all articles
Browse latest Browse all 9738

Trending Articles