PlaneGenerator.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.UIElements;
  4. public class PlaneGenerator : MonoBehaviour
  5. {
  6. public Material material;
  7. public float noiseLevel = 0.1f;
  8. private const int pqsResolution = 16;
  9. private const int sphereRadius = 10;
  10. private List<Quad> quads;
  11. // Start is called once before the first execution of Update after the MonoBehaviour is created
  12. void Start()
  13. {
  14. BuildRootQuads();
  15. UpdateMeshes();
  16. }
  17. // Update is called once per frame
  18. void Update()
  19. {
  20. }
  21. private void BuildRootQuads()
  22. {
  23. quads = new List<Quad>();
  24. var quad = BuildQuad("quadY");
  25. quads.Add(quad);
  26. RotatePlaneY(quad.Vertices);
  27. quad = BuildQuad("quadY1");
  28. quads.Add(quad);
  29. RotatePlaneY1(quad.Vertices);
  30. quad = BuildQuad("quadZ");
  31. quads.Add(quad);
  32. RotatePlaneZ(quad.Vertices);
  33. quad = BuildQuad("quadZ1");
  34. quads.Add(quad);
  35. RotatePlaneZ1(quad.Vertices);
  36. quad = BuildQuad("quadX");
  37. quads.Add(quad);
  38. RotatePlaneX(quad.Vertices);
  39. quad = BuildQuad("quadX1");
  40. quads.Add(quad);
  41. RotatePlaneX1(quad.Vertices);
  42. }
  43. private Quad BuildQuad(string name)
  44. {
  45. var (vertices, uv) = CreateVertices();
  46. var triangles = CreateTriangles();
  47. return new Quad
  48. {
  49. Name = name,
  50. Vertices = vertices,
  51. Triangles = triangles,
  52. Uv = uv
  53. };
  54. }
  55. private void UpdateMeshes()
  56. {
  57. foreach (var quad in quads)
  58. {
  59. CreateMesh(quad.Name, quad.Vertices, quad.Uv, quad.Triangles);
  60. }
  61. }
  62. private (Vector3[] vertices, Vector2[] uv) CreateVertices()
  63. {
  64. var half = sphereRadius / 2f;
  65. var vertices = new Vector3[(pqsResolution + 1) * (pqsResolution + 1)];
  66. Vector2[] uv = new Vector2[(pqsResolution + 1) * (pqsResolution + 1)];
  67. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  68. {
  69. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  70. {
  71. vertices[vertex] = new Vector3(half - (float)x / pqsResolution * sphereRadius, half, half - (float)z / pqsResolution * sphereRadius);
  72. uv[vertex] = new Vector2((float)x / pqsResolution, (float)z / pqsResolution);
  73. }
  74. }
  75. return (vertices, uv);
  76. }
  77. private int[] CreateTriangles()
  78. {
  79. var triangles = new int[(pqsResolution) * (pqsResolution) * 6];
  80. int triangle = 0;
  81. for (int x = 1, vertex = 0; x<pqsResolution + 1; x++, vertex++)
  82. {
  83. for (int z = 1; z<pqsResolution + 1; z++, vertex++)
  84. {
  85. triangles[triangle] = vertex;
  86. triangles[triangle + 1] = vertex + pqsResolution + 2;
  87. triangles[triangle + 2] = vertex + pqsResolution + 1;
  88. triangles[triangle + 3] = vertex;
  89. triangles[triangle + 4] = vertex + 1;
  90. triangles[triangle + 5] = vertex + pqsResolution + 2;
  91. triangle += 6;
  92. }
  93. }
  94. return triangles;
  95. }
  96. private void CreateMesh(string name, Vector3[] vertices, Vector2[] uv, int[] triangles)
  97. {
  98. var mesh = new GameObject(name, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider));
  99. mesh.transform.localScale = new Vector3(1, 1, 1);
  100. var meshFilter = mesh.GetComponent<MeshFilter>();
  101. meshFilter.mesh.vertices = vertices;
  102. meshFilter.mesh.triangles = triangles;
  103. meshFilter.mesh.uv = uv;
  104. mesh.GetComponent<MeshCollider>().sharedMesh = meshFilter.mesh;
  105. meshFilter.mesh.RecalculateBounds();
  106. meshFilter.mesh.RecalculateNormals();
  107. mesh.GetComponent<MeshRenderer>().material = material;
  108. }
  109. private void RotatePlaneX(Vector3[] vertices)
  110. {
  111. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  112. {
  113. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  114. {
  115. vertices[vertex] = new Vector3(vertices[vertex].y, vertices[vertex].x, -vertices[vertex].z);
  116. var noise = GetNoise(vertices[vertex].y, vertices[vertex].z);
  117. vertices[vertex] = noise * sphereRadius * Vector3.Normalize(vertices[vertex]);
  118. }
  119. }
  120. }
  121. private void RotatePlaneX1(Vector3[] vertices)
  122. {
  123. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  124. {
  125. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  126. {
  127. vertices[vertex] = new Vector3(-vertices[vertex].y, -vertices[vertex].x, -vertices[vertex].z);
  128. var noise = GetNoise(-vertices[vertex].y, -vertices[vertex].z);
  129. vertices[vertex] = noise * sphereRadius * Vector3.Normalize(vertices[vertex]);
  130. }
  131. }
  132. }
  133. private void RotatePlaneY(Vector3[] vertices)
  134. {
  135. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  136. {
  137. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  138. {
  139. var noise = GetNoise(vertices[vertex].x, vertices[vertex].z);
  140. vertices[vertex] = noise * sphereRadius * Vector3.Normalize(vertices[vertex]);
  141. }
  142. }
  143. }
  144. private void RotatePlaneY1(Vector3[] vertices)
  145. {
  146. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  147. {
  148. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  149. {
  150. vertices[vertex] = new Vector3(-vertices[vertex].x, -vertices[vertex].y, vertices[vertex].z);
  151. var noise = GetNoise(-vertices[vertex].x, -vertices[vertex].z);
  152. vertices[vertex] = noise * sphereRadius * Vector3.Normalize(vertices[vertex]);
  153. }
  154. }
  155. }
  156. private void RotatePlaneZ(Vector3[] vertices)
  157. {
  158. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  159. {
  160. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  161. {
  162. vertices[vertex] = new Vector3(-vertices[vertex].x, vertices[vertex].z, vertices[vertex].y);
  163. var noise = GetNoise(-vertices[vertex].x, vertices[vertex].y);
  164. vertices[vertex] = noise * sphereRadius * Vector3.Normalize(vertices[vertex]);
  165. }
  166. }
  167. }
  168. private void RotatePlaneZ1(Vector3[] vertices)
  169. {
  170. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  171. {
  172. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  173. {
  174. vertices[vertex] = new Vector3(-vertices[vertex].x, -vertices[vertex].z, -vertices[vertex].y);
  175. var noise = GetNoise(-vertices[vertex].x, -vertices[vertex].y);
  176. vertices[vertex] = noise * sphereRadius * Vector3.Normalize(vertices[vertex]);
  177. }
  178. }
  179. }
  180. private float GetNoise(float x, float y)
  181. {
  182. return 1 + Mathf.PerlinNoise(x, y) * noiseLevel;
  183. }
  184. }