1階のナビメッシュの無い点から最も近い1階のナビメッシュ上の点を取得してみました。
まず上のように1階と2階と階段を作ってナビメッシュをベイクしました。1階のナビメッシュには穴が開いています。
青いプレイヤーにはタグを付けて、赤い敵にはナビメッシュエージェントコンポーネントとスクリプトを付けました。
ナビメッシュエージェントの目的地にプレイヤーの位置を入れると、プレイヤーがナビメッシュの無いところにいるときに、2階のナビメッシュ上に目的地ができてしまいます。
そこで、NavMesh.SamplePositionメソッドを使って最も近いナビメッシュ上の点を探したいですが、すべてのエリアから探すとやはり2階の点が返されるので、エリアにマスクをかけます。
そのためにNavigationウィンドウのAreasタブで、新しいエリアタイプを設定しました。
シーンのPlaneオブジェクトを選択して、ObjectタブのNavigation Areaでこれらを選択します。
そしてBakeタブで再度ベイクすると、各床に別々のエリアタイプを設定できました。
エージェントのスクリプトでNavMesh.SamplePositionメソッドを呼ぶ時に引数にエリアマスクを渡します。
using UnityEngine;
using UnityEngine.AI;
public class TestAgent3 : MonoBehaviour
{
[SerializeField] float maxDistance;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
SetDestination();
}
}
void SetDestination()
{
GameObject player = GameObject.FindGameObjectWithTag("Player");
NavMeshAgent agent = GetComponent<NavMeshAgent>();
NavMeshHit hit;
// 1階のナビメッシュの最も近い点を探す
if (NavMesh.SamplePosition(player.transform.position, out hit, maxDistance, 1 << 3))
{
agent.destination = hit.position;
}
// 無いとき
else
{
agent.destination = player.transform.position;
}
}
}
これで、一階のナビメッシュから目的地を探せました。