GenerateCloudPlane.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using UnityEngine;
  2. [ExecuteInEditMode] // 编辑器下也能直接运行
  3. public class CloudPlaneGenerator : MonoBehaviour
  4. {
  5. [Header("细分度(推荐 80~150,手机别超200)")]
  6. public int subdivisions = 120;
  7. [Header("平面大小(世界单位)")]
  8. public float size = 200f; // 最终平面宽高 200×200 米
  9. [Header("一键生成(Play模式或编辑器都行)")]
  10. public bool generateNow = false;
  11. private void Update()
  12. {
  13. if (generateNow)
  14. {
  15. generateNow = false; // 防止连续生成
  16. Generate();
  17. }
  18. }
  19. [ContextMenu("手动生成云海平面")] // 右键组件 → 手动生成云海平面
  20. public void Generate()
  21. {
  22. // 确保有组件
  23. var filter = GetComponent<MeshFilter>();
  24. if (filter == null) filter = gameObject.AddComponent<MeshFilter>();
  25. var renderer = GetComponent<MeshRenderer>();
  26. if (renderer == null) renderer = gameObject.AddComponent<MeshRenderer>();
  27. Mesh mesh = new Mesh();
  28. mesh.name = "CloudSea_Plane";
  29. int vertsX = subdivisions + 1;
  30. int vertsZ = subdivisions + 1;
  31. Vector3[] vertices = new Vector3[vertsX * vertsZ];
  32. Vector2[] uv = new Vector2[vertsX * vertsZ];
  33. int[] triangles = new int[subdivisions * subdivisions * 6];
  34. float uvStep = 1f / subdivisions;
  35. float posStep = size / subdivisions;
  36. for (int z = 0; z < vertsZ; z++)
  37. {
  38. for (int x = 0; x < vertsX; x++)
  39. {
  40. int i = x + z * vertsX;
  41. // 位置:从 -size/2 到 +size/2
  42. vertices[i] = new Vector3(
  43. x * posStep - size * 0.5f,
  44. 0,
  45. z * posStep - size * 0.5f
  46. );
  47. // UV 仍然是 0~1,方便后面 Tiling 参数控制
  48. uv[i] = new Vector2(x * uvStep, z * uvStep);
  49. }
  50. }
  51. // 生成三角形
  52. int tri = 0;
  53. for (int z = 0; z < subdivisions; z++)
  54. {
  55. for (int x = 0; x < subdivisions; x++)
  56. {
  57. int i = x + z * vertsX;
  58. triangles[tri++] = i;
  59. triangles[tri++] = i + vertsX;
  60. triangles[tri++] = i + 1;
  61. triangles[tri++] = i + 1;
  62. triangles[tri++] = i + vertsX;
  63. triangles[tri++] = i + vertsX + 1;
  64. }
  65. }
  66. mesh.vertices = vertices;
  67. mesh.uv = uv;
  68. mesh.triangles = triangles;
  69. mesh.RecalculateNormals();
  70. mesh.RecalculateBounds();
  71. filter.sharedMesh = mesh;
  72. // 自动放大(很多人忘记这一步!)
  73. transform.localScale = Vector3.one;
  74. // 如果没有材质,给一个默认的防止粉红
  75. if (renderer.sharedMaterial == null)
  76. {
  77. renderer.sharedMaterial = new Material(Shader.Find("Universal Render Pipeline/Unlit"));
  78. }
  79. Debug.Log($"云海平面生成完成!顶点数:{vertices.Length} 三角形:{triangles.Length / 3}");
  80. }
  81. }