public TerrainChunk(Vector2 coord, int size, LoDInfo[] detailLevels, Transform parent, Material material) { this.detailLevels = detailLevels; position = coord * size; Vector3 positionV3 = new Vector3(position.x, 0, position.y); bounds = new Bounds(position, Vector2.one * size); meshObject = new GameObject("Terrain Chunk"); meshRenderer = meshObject.AddComponent <MeshRenderer>(); meshRenderer.material = material; meshFilter = meshObject.AddComponent <MeshFilter>(); meshCollider = meshObject.AddComponent <MeshCollider>(); meshObject.transform.position = positionV3 * mapGenerator.terrainData.uniformScale; meshObject.transform.parent = parent; meshObject.transform.localScale = Vector3.one * mapGenerator.terrainData.uniformScale; SetVisible(false); lodMeshes = new LoDMesh[detailLevels.Length]; for (int i = 0; i < detailLevels.Length; i++) { lodMeshes[i] = new LoDMesh(detailLevels[i].lod, UpdateTerrainChunk); if (detailLevels[i].useForCollider) { collisionLoDMesh = lodMeshes[i]; } } mapGenerator.RequestMapData(position, OnMapDataReceived); }
public void UpdateTerrainChunk() { if (mapDataReceived) { float viewerDistanceFromNearestEdge = Mathf.Sqrt(bounds.SqrDistance(viewerPosition)); bool visible = viewerDistanceFromNearestEdge <= maxViewDistance; if (visible) { int lodIndex = 0; for (int i = 0; i < detailLevels.Length - 1; i++) { if (viewerDistanceFromNearestEdge > detailLevels[i].visibleDistanceThreshold) { lodIndex = i + 1; } else { break; } } if (lodIndex != previousLoDIndex) { LoDMesh lodMesh = lodMeshes[lodIndex]; if (lodMesh.hasMesh) { previousLoDIndex = lodIndex; meshFilter.mesh = lodMesh.mesh; } else if (!lodMesh.hasRequestedMesh) { lodMesh.RequestMesh(mapData); } } if (lodIndex == 0) { if (collisionLoDMesh.hasMesh) { meshCollider.sharedMesh = collisionLoDMesh.mesh; } else if (!collisionLoDMesh.hasRequestedMesh) { collisionLoDMesh.RequestMesh(mapData); } } terrainChunkVisibleLastUpdate.Add(this); } SetVisible(visible); } }