MeshTool.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using UnityEngine.AI;
  4. namespace Unity.AI.Navigation.Samples
  5. {
  6. /// <summary>
  7. /// Manipulation tool for displacing the vertices in a list of meshes
  8. /// </summary>
  9. [DefaultExecutionOrder(-101)]
  10. public class MeshTool : MonoBehaviour
  11. {
  12. NavMeshSurface m_Surface;
  13. public enum ExtrudeMethod
  14. {
  15. Vertical,
  16. MeshNormal
  17. }
  18. public List<MeshFilter> m_Filters = new List<MeshFilter>();
  19. public float m_Radius = 1.5f;
  20. public float m_Power = 2.0f;
  21. public ExtrudeMethod m_Method = ExtrudeMethod.Vertical;
  22. RaycastHit m_HitInfo = new RaycastHit();
  23. AsyncOperation m_LastNavMeshUpdate;
  24. void OnEnable()
  25. {
  26. Cursor.lockState = CursorLockMode.Locked;
  27. Cursor.visible = false;
  28. m_Surface = GetComponent<NavMeshSurface>();
  29. if (m_Surface != null)
  30. {
  31. m_Surface.BuildNavMesh();
  32. m_LastNavMeshUpdate = m_Surface.UpdateNavMesh(m_Surface.navMeshData);
  33. }
  34. }
  35. void Update()
  36. {
  37. var ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
  38. if (Physics.Raycast(ray.origin, ray.direction, out m_HitInfo))
  39. {
  40. Debug.DrawRay(m_HitInfo.point, m_HitInfo.normal, Color.red);
  41. Vector3 displacement = (m_Method == ExtrudeMethod.Vertical) ? Vector3.up : m_HitInfo.normal;
  42. if (Input.GetMouseButton(0) || (Input.GetKey(KeyCode.Space) && !Input.GetKey(KeyCode.LeftShift)))
  43. {
  44. ModifyMesh(m_Power * displacement, m_HitInfo.point);
  45. if (m_Surface != null)
  46. {
  47. if (m_LastNavMeshUpdate.isDone)
  48. m_LastNavMeshUpdate = m_Surface.UpdateNavMesh(m_Surface.navMeshData);
  49. }
  50. }
  51. else if (Input.GetMouseButton(1) || (Input.GetKey(KeyCode.Space) && Input.GetKey(KeyCode.LeftShift)))
  52. {
  53. ModifyMesh(-m_Power * displacement, m_HitInfo.point);
  54. if(m_Surface != null)
  55. {
  56. if (m_LastNavMeshUpdate.isDone)
  57. m_LastNavMeshUpdate = m_Surface.UpdateNavMesh(m_Surface.navMeshData);
  58. }
  59. }
  60. else if(Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1) || Input.GetKeyUp(KeyCode.Space))
  61. {
  62. if (m_Surface != null)
  63. {
  64. if (!m_LastNavMeshUpdate.isDone)
  65. NavMeshBuilder.Cancel(m_Surface.navMeshData);
  66. m_LastNavMeshUpdate = m_Surface.UpdateNavMesh(m_Surface.navMeshData);
  67. }
  68. }
  69. }
  70. }
  71. void ModifyMesh(Vector3 displacement, Vector3 center)
  72. {
  73. foreach (var filter in m_Filters)
  74. {
  75. Mesh mesh = filter.mesh;
  76. Vector3[] vertices = mesh.vertices;
  77. for (int i = 0; i < vertices.Length; ++i)
  78. {
  79. Vector3 v = filter.transform.TransformPoint(vertices[i]);
  80. vertices[i] = vertices[i] + displacement * Gaussian(v, center, m_Radius);
  81. }
  82. mesh.vertices = vertices;
  83. mesh.RecalculateBounds();
  84. var col = filter.GetComponent<MeshCollider>();
  85. if (col != null)
  86. {
  87. var colliMesh = new Mesh();
  88. colliMesh.vertices = mesh.vertices;
  89. colliMesh.triangles = mesh.triangles;
  90. col.sharedMesh = colliMesh;
  91. }
  92. }
  93. }
  94. static float Gaussian(Vector3 pos, Vector3 mean, float dev)
  95. {
  96. float x = pos.x - mean.x;
  97. float y = pos.y - mean.y;
  98. float z = pos.z - mean.z;
  99. float n = 1.0f / (2.0f * Mathf.PI * dev * dev);
  100. return n * Mathf.Pow(2.718281828f, -(x * x + y * y + z * z) / (2.0f * dev * dev));
  101. }
  102. }
  103. }