制作地形:
- 绘制方块
- 逐个绘制方块并加噪波高度
- 删除Gizmos和逐个绘制
1.draw quad
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class mesh_generator : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
CreateShape();
UpdateMesh();
}
// Update is called once per frame
void CreateShape()
{
vertices = new Vector3[]
{
new Vector3 (0,0,0),
new Vector3 (0,0,1),
new Vector3 (1,0,0),
new Vector3 (1,0,1)
};
triangles = new int[]
{
0,
1,
2,
1,3,2//1,2,3 will have back face culling problem.
};
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
2.逐块生成地形
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class mesh_generator : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
public int xSize = 20;
public int zSize = 20;
//vertex count = (xSize+1)*(zSize+1)
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
StartCoroutine(CreateShape());
}
private void Update()
{
UpdateMesh();
}
// Update is called once per frame
//void CreateShape()
IEnumerator CreateShape()
{
vertices = new Vector3[(xSize + 1) * (zSize + 1)];
for (int i = 0,z =0; z <= zSize; z++)
{
for(int x = 0; x <= xSize; x++)
{
float y = Mathf.PerlinNoise(x*.4f, z * .4f) * 2f;//*.3f for scale
vertices[i] = new Vector3(x, y, z);
i++;
}
}
triangles = new int[xSize*zSize*6];
int vert = 0;
int index =0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
triangles[index + 0] = vert + 0;
triangles[index + 1] = vert + xSize + 1;
triangles[index + 2] = vert + 1;
triangles[index + 3] = vert + 1;
triangles[index + 4] = vert + xSize + 1;
triangles[index + 5] = vert + xSize + 2;
vert++;
index += 6;
yield return new WaitForSeconds(.01f);
}
vert++;//3*3, 行结束后 vert++,vert = 4, index = 18
}
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
private void OnDrawGizmos()
{
if (vertices == null)
return;
for (int i = 0; i < vertices.Length; i++)
{
Gizmos.DrawSphere(vertices[i], .1f);
}
}
}
3.最终效果
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class mesh_generator : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
public int xSize = 20;
public int zSize = 20;
//vertex count = (xSize+1)*(zSize+1)
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
//StartCoroutine(CreateShape());
CreateShape();
UpdateMesh();
}
//private void Update()
//{
// UpdateMesh();
//}
// Update is called once per frame
void CreateShape()
//IEnumerator CreateShape()
{
vertices = new Vector3[(xSize + 1) * (zSize + 1)];
for (int i = 0,z =0; z <= zSize; z++)
{
for(int x = 0; x <= xSize; x++)
{
float y = Mathf.PerlinNoise(x*.4f, z * .4f) * 2f;//*.3f for scale
vertices[i] = new Vector3(x, y, z);
i++;
}
}
triangles = new int[xSize*zSize*6];
int vert = 0;
int index =0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
triangles[index + 0] = vert + 0;
triangles[index + 1] = vert + xSize + 1;
triangles[index + 2] = vert + 1;
triangles[index + 3] = vert + 1;
triangles[index + 4] = vert + xSize + 1;
triangles[index + 5] = vert + xSize + 2;
vert++;
index += 6;
//yield return new WaitForSeconds(.01f);//yield return 只能在协程(即 IEnumerator 类型的函数)中使用
}
vert++;//3*3, 行结束后 vert++,vert = 4, index = 18
}
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
generate Gizmos
//private void OnDrawGizmos()
//{
// if (vertices == null)
// return;
// for (int i = 0; i < vertices.Length; i++)
// {
// Gizmos.DrawSphere(vertices[i], .1f);
// }
//}
}
附:叠加perlin noise
float y =amplitude1 * Mathf.PerlinNoise(x * frequency1,z * frequency1)
+ amplitude2 * Mathf.PerlinNoise(x * frequency2, z * frequency2)
+ amplitude3 * Mathf.PerlinNoise(x * frequency3, z * frequency3)
* noiseStrength;
程序化生成颜色
0.用贴图
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class mesh_generator : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
Vector2[]uvs;
public int xSize = 20;
public int zSize = 20;
//vertex count = (xSize+1)*(zSize+1)
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
//StartCoroutine(CreateShape());
CreateShape();
UpdateMesh();
}
//private void Update()
//{
// UpdateMesh();
//}
// Update is called once per frame
void CreateShape()
//IEnumerator CreateShape()
{
vertices = new Vector3[(xSize + 1) * (zSize + 1)];
for (int i = 0,z =0; z <= zSize; z++)
{
for(int x = 0; x <= xSize; x++)
{
float y = Mathf.PerlinNoise(x*.4f, z * .4f) * 2f;//*.3f for scale
vertices[i] = new Vector3(x, y, z);
i++;
}
}
triangles = new int[xSize*zSize*6];
int vert = 0;
int index =0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
triangles[index + 0] = vert + 0;
triangles[index + 1] = vert + xSize + 1;
triangles[index + 2] = vert + 1;
triangles[index + 3] = vert + 1;
triangles[index + 4] = vert + xSize + 1;
triangles[index + 5] = vert + xSize + 2;
vert++;
index += 6;
//yield return new WaitForSeconds(.01f);//yield return 只能在协程(即 IEnumerator 类型的函数)中使用
}
vert++;//3*3, 行结束后 vert++,vert = 4, index = 18
}
uvs = new Vector2[vertices.Length];
for (int i = 0, z = 0; z <= zSize; z++)
{
for (int x = 0; x <= xSize; x++)
{
uvs[i]=new Vector2((float)x/xSize,(float)z/zSize);
i++;
}
}
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
mesh.RecalculateNormals();
}
generate Gizmos
//private void OnDrawGizmos()
//{
// if (vertices == null)
// return;
// for (int i = 0; i < vertices.Length; i++)
// {
// Gizmos.DrawSphere(vertices[i], .1f);
// }
//}
}
1.根据高度给颜色 并用Shader Graph获取vertex color

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class mesh_generator : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
//Vector2[]uvs;
Color[] colors;
public int xSize = 20;
public int zSize = 20;
public Gradient gradient;
float minTerrainHeight;
float maxTerrainHeight;
//normalize height
//vertex count = (xSize+1)*(zSize+1)
// Start is called before the first frame update
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
//StartCoroutine(CreateShape());
CreateShape();
UpdateMesh();
}
//private void Update()
//{
// UpdateMesh();
//}
// Update is called once per frame
void CreateShape()
//IEnumerator CreateShape()
{
vertices = new Vector3[(xSize + 1) * (zSize + 1)];
for (int i = 0,z =0; z <= zSize; z++)
{
for(int x = 0; x <= xSize; x++)
{
float y = Mathf.PerlinNoise(x*.4f, z * .4f) * 2f;//*.3f for scale
vertices[i] = new Vector3(x, y, z);
if(y>maxTerrainHeight)
maxTerrainHeight = y;
if(y<minTerrainHeight)
minTerrainHeight = y;
i++;
}
}
triangles = new int[xSize*zSize*6];
int vert = 0;
int index =0;
for (int z = 0; z < zSize; z++)
{
for (int x = 0; x < xSize; x++)
{
triangles[index + 0] = vert + 0;
triangles[index + 1] = vert + xSize + 1;
triangles[index + 2] = vert + 1;
triangles[index + 3] = vert + 1;
triangles[index + 4] = vert + xSize + 1;
triangles[index + 5] = vert + xSize + 2;
vert++;
index += 6;
//yield return new WaitForSeconds(.01f);//yield return 只能在协程(即 IEnumerator 类型的函数)中使用
}
vert++;//3*3, 行结束后 vert++,vert = 4, index = 18
}
//uvs = new Vector2[vertices.Length];
colors = new Color[vertices.Length];
for (int i = 0, z = 0; z <= zSize; z++)
{
for (int x = 0; x <= xSize; x++)
{
//uvs[i]=new Vector2((float)x/xSize,(float)z/zSize);
float height = Mathf.InverseLerp(minTerrainHeight, maxTerrainHeight, vertices[i].y);
colors[i] = gradient.Evaluate(height);
i++;
}
}
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.colors = colors;
mesh.RecalculateNormals();
}
generate Gizmos
//private void OnDrawGizmos()
//{
// if (vertices == null)
// return;
// for (int i = 0; i < vertices.Length; i++)
// {
// Gizmos.DrawSphere(vertices[i], .1f);
// }
//}
}