Unity で 2DRPG を作ってみようと奮闘してます。
今回は、NPC 同士の重なり合いや、通り抜けできない部分を NPC がすり抜けちゃう問題を解消するために「NavMesh Agent」というものを使って NPC の移動部分を作成してみました。
NavMesh Agent とは
NavMesh Agent は「キャラクターを自動的に移動させられる機能」です。
これを使えば自動で動くキャラクターが作ることができます。
プレイ動画
動作検証してた時のプレイ動画です。
www.youtube.com
事前作業
NavMeshをベイク
以下のシーンのTilemapに通れる場所と通れない場所を設定します。
設定後にNavMeshをベイクすると移動可能部分が青色になります。
(通れない場所の設定が荒い。。。)
設定メモ
NavMeshPlus
今回は「NavMeshPlus」というものを利用してNavMeshAgentの設定を行いました。
github.com
とりあえずマスターブランチのものを持ってきてマニュアルらしきものを読みます。
NavMeshModifierの設定
「Tilemap」を設定しているところに、「NavMeshModifier」というものを追加して、通れる場所と通れない場所を教えてあげます。
通れる場所
以下が通れる場所の「Tilemap」です。
「NavMeshModifier」を追加後に「Walkable」を選択します。
通れる場所
以下が通れない場所の「Tilemap」です。
「NavMeshModifier」を追加後に「Not Walkable」を選択します。
NavMeshSurface2dの設定
適当なGameObjectを作成後「NavMeshSurface2d」を追加します。
「Bake」ボタンをクリックすると、移動可能部分が青色になります。
(ならないときは、「Rotate Surface to XY」ボタンを押してみるといいかもです)
NPCの設定
Nav Mesh Agentの設定
NPCに「Nav Mesh Agent」の設定を追加します。
鬼ごっこ用のスクリプト作成
鬼ごっこ用のスクリプトを作成します。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class Chase2 : MonoBehaviour { public GameObject target; private NavMeshAgent agent; public Animator animator; GameObject playerObj; public float distance; float time; void Start() { agent = GetComponent<NavMeshAgent>(); agent.updateRotation = false; agent.updateUpAxis = false; } void FixedUpdate() { playerObj = GameObject.Find("Player(Clone)"); float now = Vector2.Distance(transform.position, playerObj.transform.position); if (distance < now) { agent.destination = playerObj.transform.position; Vector2? vector = new Vector2( agent.destination.x - transform.position.x, agent.destination.y - transform.position.y ); setStateToAnimator(vector: vector != Vector2.zero ? vector : (Vector2?)null); } } private void setStateToAnimator(Vector2? vector) { if (!vector.HasValue) { this.animator.speed = 0.0f; return; } this.animator.speed = 1.0f; this.animator.SetFloat("x", vector.Value.x); this.animator.SetFloat("y", vector.Value.y); } }