using System; using UnityEditor; using UnityEngine; public static class GroundCreate { //[MenuItem("GroundTools/GroundCreate")] /// /// 创建一个100x100单位的地表模型 /// public static void CreateGround() { // 设置网格参数 int width = 128; int length = 128; // 创建游戏对象 GameObject ground = new GameObject($"Ground"); // 添加网格过滤器和网格渲染器 MeshFilter meshFilter = ground.AddComponent(); MeshRenderer meshRenderer = ground.AddComponent(); UnityEngine.Random.InitState((int)DateTime.Now.Ticks); float randOffset = UnityEngine.Random.Range(0f, 100f); // 创建网格 Mesh mesh = new Mesh(); mesh.name = $"Ground_{width}X{length}_Mesh"; float halfWidth = width * 0.5f; float halfLength = length * 0.5f; //创建一个随机高度图,并填入到顶点的y上 float[,] heightMap = GenerateHeightMap(width, length); //for (int z = 0; z <= length; z++) //{ // for (int x = 0; x <= width; x++) // { // heightMap[x, z] = Mathf.PerlinNoise(x * 0.1f, z * 0.1f) * 2f - 1f; // } //} // 创建顶点 Vector3[] vertices = new Vector3[(width + 1) * (length + 1)]; for (int z = 0; z <= length; z++) { for (int x = 0; x <= width; x++) { vertices[z * (width + 1) + x] = new Vector3(x - halfWidth, heightMap[x, z], z - halfLength); } } // 创建三角形 int[] triangles = new int[width * length * 6]; int triangleIndex = 0; for (int z = 0; z < length; z++) { for (int x = 0; x < width; x++) { int vertexIndex = z * (width + 1) + x; triangles[triangleIndex++] = vertexIndex; triangles[triangleIndex++] = vertexIndex + width + 1; triangles[triangleIndex++] = vertexIndex + 1; triangles[triangleIndex++] = vertexIndex + 1; triangles[triangleIndex++] = vertexIndex + width + 1; triangles[triangleIndex++] = vertexIndex + width + 2; } } // 创建UV坐标 Vector2[] uvs = new Vector2[(width + 1) * (length + 1)]; for (int z = 0; z <= length; z++) { for (int x = 0; x <= width; x++) { uvs[z * (width + 1) + x] = new Vector2((float)x / width, (float)z / length); } } // 设置网格数据 mesh.vertices = vertices; mesh.triangles = triangles; mesh.uv = uvs; mesh.RecalculateNormals(); mesh.RecalculateBounds(); // 应用网格 meshFilter.sharedMesh = mesh; // 添加碰撞器 MeshCollider collider = ground.AddComponent(); collider.sharedMesh = mesh; // 设置材质 meshRenderer.material = new Material(Shader.Find("XWorld/XTerrain")); //设置_LayerTex0 _LayerTex1 _LayerTex2 _LayerTex3 和_Control贴图 meshRenderer.material.SetTexture("_LayerTex0", AssetDatabase.LoadAssetAtPath("Assets/Arts/scene/Terrain/Texture/grass.png")); meshRenderer.material.SetTexture("_LayerTex1", AssetDatabase.LoadAssetAtPath("Assets/Arts/scene/Terrain/Texture/blick.png")); meshRenderer.material.SetTexture("_LayerTex2", AssetDatabase.LoadAssetAtPath("Assets/Arts/scene/Terrain/Texture/mud.png")); meshRenderer.material.SetTexture("_LayerTex3", AssetDatabase.LoadAssetAtPath("Assets/Arts/scene/Terrain/Texture/sand.png")); //生成一个rgba四通道的控制贴图,随机分配四种材质的混合度 Texture2D controlTex = new Texture2D(width, length, TextureFormat.RGBA32, false); float PerlinRandom = 0.05f; for (int z = 0; z < length; z++) { for (int x = 0; x < width; x++) { //float h = heightMap[x, z]; float h1 = Mathf.PerlinNoise(randOffset + z * PerlinRandom, randOffset + x * PerlinRandom); float hLerp; Color color;// = new Color(0, 0, 0, 0); if (h1 < 0.33f) { hLerp = (0.33f - h1)*3; color = new Color(0, 0, hLerp, 1 - hLerp); } else if (h1 < 0.66f) { hLerp = (0.66f - h1) * 3; color = new Color(0, hLerp, 1- hLerp, 0); } else { hLerp = (1.0f - h1) * 3; color = new Color(hLerp, 1 - hLerp, 0, 0); } controlTex.SetPixel(x, z, color); } } controlTex.Apply(); meshRenderer.material.SetTexture("_Control", controlTex); // 注册撤销操作并选中对象 Undo.RegisterCreatedObjectUndo(ground, "Create 100x100 Ground"); Selection.activeGameObject = ground; } //生成x * z的高度图,增加一个浮动变化的高度和一个不均匀的高度变化 //heightScale 高度缩放因子 //heightOffset 高度偏移量 public static float[,] GenerateHeightMap(int x, int z, float heightScale = 20f, float PerlinRandom = 0.01f) { float[,] heightMap = new float[x + 1, z + 1]; UnityEngine.Random.InitState(Time.frameCount); Debug.Log("Random Seed: " + Time.frameCount); //生成一个N分之一宽和高的高度图 int N = 16; int quarterX = x / N; int quarterZ = z / N; float[,] quarterHeightMap = new float[quarterX + 1, quarterZ + 1]; for (int i = 0; i <= quarterX; i++) { for (int j = 0; j <= quarterZ; j++) { quarterHeightMap[i, j] = Mathf.PerlinNoise(i * 0.1f, j * 0.1f) * heightScale*2; } } //将四分之一高度图叠加到总的高度图上 for (int i = 0; i <= x; i++) { for (int j = 0; j <= z; j++) { //heightMap[i, j] = Mathf.PerlinNoise(i * 0.1f, j * 0.1f) * heightScale + quarterHeightMap[i / N, j / N]; //heightMap[i, j] = quarterHeightMap[i / N, j / N]; float h1 = Mathf.PerlinNoise(i * PerlinRandom, j * PerlinRandom) * heightScale; float h2 = Mathf.PerlinNoise(i * PerlinRandom*5, j * PerlinRandom*5) * heightScale; heightMap[i, j] = h1 > h2? h1 : h2; } } return heightMap; } }