MeshGenerator
public static MeshData GenerateTerrainMesh(float[,] heightMap,float
heightMultiplier,AnimationCurve heightCurve)
...
meshData.vertices[vertexIndex] = new Vector3
(x + topLeftX,heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y);
//MapGenerator.cs
const int mapChunkSize = 241;
[Range(0, 6)]
public int levelOfDetail;
float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, noiseScale,octaves,persistance,lacunarity,offsets,seed);
Color[] colourMap = new Color[mapChunkSize * mapChunkSize];
for(int y = 0;y < mapChunkSize; y++)
{
for(int x = 0;x < mapChunkSize; x++)
{
float currentHeight = noiseMap[x, y];
for(int i = 0;i < regions.Length;i++)
{
if(currentHeight <= regions[i].height)
{
colourMap[y * mapChunkSize + x] = regions[i].colour;
break;
}
}
}
}
int Simplification = lod * 2;
int verticesPerLine = (width - 1) / Simplification + 1;
MeshData meshData = new MeshData(verticesPerLine, verticesPerLine);
for (int y = 0;y < height;y += Simplification){
for(int x = 0;x < width;x += Simplification)
//MeshGenerator.cs
然后是无限地形
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EndlessTerrain : MonoBehaviour
{
public const float maxViewDst = 450;
public Transform viewer;
public static Vector2 viewerPosition;
int chunkSize;
int chunkVisibleInViewDst;
Dictionary<Vector2, TerrainChunk> terrainChunkDictionary
= new Dictionary<Vector2, TerrainChunk>();
List<TerrainChunk> ChunkVisUpdate = new List<TerrainChunk>();
private void Start()
{
chunkSize = MapGenerator.mapChunkSize - 1;
chunkVisibleInViewDst = Mathf.RoundToInt(maxViewDst / chunkSize);
}
private void Update()
{
viewerPosition = new Vector2(viewer.position.x, viewer.position.z);
UpdateVisibleChunks();
}
void UpdateVisibleChunks()
{
for(int i = 0;i < ChunkVisUpdate.Count;i++)
{
ChunkVisUpdate[i].SetVisible(false);
}
ChunkVisUpdate.Clear();
int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / chunkSize);
int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / chunkSize);
for(int yOffset = -chunkVisibleInViewDst;yOffset <= chunkVisibleInViewDst;yOffset++)
{
for(int xOffset = -chunkVisibleInViewDst;xOffset <= chunkVisibleInViewDst;xOffset++)
{
Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
if(terrainChunkDictionary.ContainsKey(viewedChunkCoord))
{
terrainChunkDictionary[viewedChunkCoord].UpdateTerrainChunk();
if(terrainChunkDictionary[viewedChunkCoord].IsVisible())
{
ChunkVisUpdate.Add(terrainChunkDictionary[viewedChunkCoord]);
}
}else
{
terrainChunkDictionary.Add(viewedChunkCoord, new TerrainChunk(viewedChunkCoord,chunkSize,transform));
}
}
}
}
public class TerrainChunk
{
GameObject meshObject;
Vector2 position;
Bounds bounds;
public TerrainChunk(Vector2 coord,int size,Transform parent)
{
position = coord * size;
bounds = new Bounds(position, Vector2.one * size);
Vector3 positionV3 = new Vector3(position.x, 0, position.y);
meshObject = GameObject.CreatePrimitive(PrimitiveType.Plane);
meshObject.transform.position = positionV3;
meshObject.transform.localScale = Vector3.one * size / 10f;
meshObject.transform.parent = parent;
SetVisible(false);
}
public void UpdateTerrainChunk()
{
float viewerDstFromNearestEdge = Mathf.Sqrt(bounds.SqrDistance(viewerPosition));
bool visible = viewerDstFromNearestEdge <= maxViewDst;
SetVisible(visible);
}
public void SetVisible(bool visible)
{
meshObject.SetActive(visible);
}
public bool IsVisible()
{
return meshObject.activeSelf;
}
}
}
Viewer就是个正方体
第8集第10分钟以后的没看