ナビメッシュエージェントから目的地までの経路に沿った距離を表示してみます。
ナビメッシュの経路のコーナーポイントは、通過するたびに一つずつ減っていくようです。今ある2番目のコーナーポイントを通過すると、1番目のコーナーポイントが削除されます。
なので、コーナーポイントを順番にみていって、隣り合うコーナーポイントの間の距離を足し合わせました。2番目のときはナビメッシュエージェントとの距離を使います。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;
public class PathLengthTest : MonoBehaviour
{
[SerializeField] GameObject sphere;
[SerializeField] Text text;
NavMeshAgent agent;
bool havePath = false;
Plane groundPlane;
float rayDistance;
public float planeDistance = 0f;
Vector3[] corners;
int previousCornersLength = 0;
// Start is called before the first frame update
void Start()
{
corners = default;
agent = GetComponent<NavMeshAgent>();
groundPlane = new Plane(Vector3.up, planeDistance);
}
// Update is called once per frame
void Update()
{
if (corners != default)
{
// コーナーポイントの数が変われば球を置き直す
if (previousCornersLength != agent.path.corners.Length)
{
// 緑の球を削除
GameObject[] greenSpheres = GameObject.FindGameObjectsWithTag("GreenSphere");
if (greenSpheres.Length != 0)
{
foreach (GameObject s in greenSpheres)
{
Destroy(s);
}
}
corners = agent.path.corners; // コーナーポイントを取得
// コーナーポイントに緑の球を配置
for (int i = 0; i < corners.Length; i++)
{
// 緑の球を配置
Instantiate(sphere, corners[i], sphere.transform.rotation);
}
}
// 経路ののこりの長さを表示
corners = agent.path.corners; // コーナーポイントを取得
float pathLength = 0f;
Vector3 agentPos = transform.position;
for (int i = 1; i < corners.Length;i++)
{
if (i == 1)
{
pathLength += Vector3.Distance(corners[i], agentPos);
}
else {
pathLength += Vector3.Distance(corners[i], corners[i - 1]);
}
}
text.text = Mathf.Floor(pathLength * 10) / 10 + "m";
}
// 左クリックで目的地を設定
if (Input.GetMouseButtonDown(0))
{
agent.destination = GetCursorPosition3D(); // 目的地を設定
havePath = false;
}
// パスを取得してコーナーポイントに緑の球を置く
if (!havePath && !agent.pathPending)
{
// 緑の球を削除
GameObject[] greenSpheres = GameObject.FindGameObjectsWithTag("GreenSphere");
if (greenSpheres.Length != 0)
{
foreach (GameObject s in greenSpheres)
{
Destroy(s);
}
}
havePath = true;
NavMeshPath path = agent.path;
corners = path.corners; // コーナーポイントを取得
// コーナーポイントに緑の球を配置
for (int i = 0; i < corners.Length; i++)
{
// 緑の球を配置
Instantiate(sphere, corners[i], sphere.transform.rotation);
}
}
previousCornersLength = corners.Length;
}
Vector3 GetCursorPosition3D()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルから、カメラが向く方へのレイ
groundPlane.Raycast(ray, out rayDistance); // レイを飛ばす
return ray.GetPoint(rayDistance); // Planeとレイがぶつかった点の座標を返す
}
}
反対方向の目的地を設定して、ナビメッシュエージェントが1番目のコーナーポイントを新しい目的地と逆方向に通り過ぎてしまったときも1番目を無視しますがあまり問題ないと思います。