【Unity】ナビメッシュの経路の長さを表示する

投稿者: | 2020-07-23

ナビメッシュエージェントから目的地までの経路に沿った距離を表示してみます。

ナビメッシュの経路のコーナーポイントは、通過するたびに一つずつ減っていくようです。今ある2番目のコーナーポイントを通過すると、1番目のコーナーポイントが削除されます。

なので、コーナーポイントを順番にみていって、隣り合うコーナーポイントの間の距離を足し合わせました。2番目のときはナビメッシュエージェントとの距離を使います。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. using UnityEngine.UI;
  6.  
  7. public class PathLengthTest : MonoBehaviour
  8. {
  9. [SerializeField] GameObject sphere;
  10. [SerializeField] Text text;
  11.  
  12. NavMeshAgent agent;
  13. bool havePath = false;
  14. Plane groundPlane;
  15. float rayDistance;
  16. public float planeDistance = 0f;
  17. Vector3[] corners;
  18.  
  19. int previousCornersLength = 0;
  20.  
  21. // Start is called before the first frame update
  22. void Start()
  23. {
  24. corners = default;
  25. agent = GetComponent<NavMeshAgent>();
  26. groundPlane = new Plane(Vector3.up, planeDistance);
  27. }
  28.  
  29. // Update is called once per frame
  30. void Update()
  31. {
  32. if (corners != default)
  33. {
  34.  
  35. // コーナーポイントの数が変われば球を置き直す
  36. if (previousCornersLength != agent.path.corners.Length)
  37. {
  38.  
  39. // 緑の球を削除
  40. GameObject[] greenSpheres = GameObject.FindGameObjectsWithTag("GreenSphere");
  41.  
  42. if (greenSpheres.Length != 0)
  43. {
  44. foreach (GameObject s in greenSpheres)
  45. {
  46. Destroy(s);
  47. }
  48. }
  49.  
  50. corners = agent.path.corners; // コーナーポイントを取得
  51.  
  52. // コーナーポイントに緑の球を配置
  53. for (int i = 0; i < corners.Length; i++)
  54. {
  55. // 緑の球を配置
  56. Instantiate(sphere, corners[i], sphere.transform.rotation);
  57.  
  58. }
  59.  
  60. }
  61.  
  62. // 経路ののこりの長さを表示
  63. corners = agent.path.corners; // コーナーポイントを取得
  64. float pathLength = 0f;
  65. Vector3 agentPos = transform.position;
  66.  
  67. for (int i = 1; i < corners.Length;i++)
  68. {
  69. if (i == 1)
  70. {
  71. pathLength += Vector3.Distance(corners[i], agentPos);
  72. }
  73. else {
  74. pathLength += Vector3.Distance(corners[i], corners[i - 1]);
  75.  
  76. }
  77. }
  78.  
  79. text.text = Mathf.Floor(pathLength * 10) / 10 + "m";
  80. }
  81.  
  82.  
  83. // 左クリックで目的地を設定
  84. if (Input.GetMouseButtonDown(0))
  85. {
  86. agent.destination = GetCursorPosition3D(); // 目的地を設定
  87. havePath = false;
  88. }
  89.  
  90. // パスを取得してコーナーポイントに緑の球を置く
  91. if (!havePath && !agent.pathPending)
  92. {
  93. // 緑の球を削除
  94. GameObject[] greenSpheres = GameObject.FindGameObjectsWithTag("GreenSphere");
  95.  
  96. if (greenSpheres.Length != 0)
  97. {
  98. foreach (GameObject s in greenSpheres)
  99. {
  100. Destroy(s);
  101. }
  102. }
  103.  
  104.  
  105. havePath = true;
  106. NavMeshPath path = agent.path;
  107. corners = path.corners; // コーナーポイントを取得
  108.  
  109. // コーナーポイントに緑の球を配置
  110. for (int i = 0; i < corners.Length; i++)
  111. {
  112. // 緑の球を配置
  113. Instantiate(sphere, corners[i], sphere.transform.rotation);
  114.  
  115. }
  116. }
  117.  
  118. previousCornersLength = corners.Length;
  119. }
  120.  
  121. Vector3 GetCursorPosition3D()
  122. {
  123. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // マウスカーソルから、カメラが向く方へのレイ
  124. groundPlane.Raycast(ray, out rayDistance); // レイを飛ばす
  125.  
  126. return ray.GetPoint(rayDistance); // Planeとレイがぶつかった点の座標を返す
  127. }
  128. }

反対方向の目的地を設定して、ナビメッシュエージェントが1番目のコーナーポイントを新しい目的地と逆方向に通り過ぎてしまったときも1番目を無視しますがあまり問題ないと思います。

コメントを残す

メールアドレスが公開されることはありません。