Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- public enum TerrainType {
- Lowlands,
- Highlands,
- Mountains
- }
- public enum BiomeType {
- Grasslands,
- Forest,
- Desert,
- Ice
- }
- [RequireComponent (typeof(MeshFilter))]
- [RequireComponent (typeof(MeshCollider))]
- public class Chunk : MonoBehaviour {
- public int height = 40;
- public int groundHeight = 8;
- public byte[,,] map;
- protected Mesh mesh;
- protected List<Vector3> verts = new List<Vector3>();
- protected List<int> tris = new List<int>();
- protected List<Vector2> uv = new List<Vector2>();
- protected MeshCollider meshCollider;
- public List<GameObject> targets = new List<GameObject>();
- protected bool initialized = false;
- protected int width;
- // Use this for initialization
- void Start () {
- width = Terrain.activeTerrain.chunkSize;
- map = new byte[width, height, width];
- TerrainType terrainType = GetTerrainFor(transform.position.x, transform.position.z);
- BiomeType biomeType = GetBiomeFor(transform.position.x, transform.position.z);
- float myHeight = GetHeightOf(terrainType);
- byte dirt = Terrain.blocks.GetBlockByte("Dirt");
- byte grassydirt = Terrain.blocks.GetBlockByte("GrassyDirt");
- byte ice = Terrain.blocks.GetBlockByte("Ice");
- byte sand = Terrain.blocks.GetBlockByte("Sand");
- for (int x = 0; x < width; x++)
- {
- float percent = (float)x / (float)(width - 1);
- float xBalance = CurvePoint(
- percent,
- (GetHeightOf(transform.position.x - width, transform.position.z) + myHeight) / 2,
- myHeight,
- (GetHeightOf(transform.position.x + width, transform.position.z) + myHeight) / 2);
- for (int z = 0; z < width; z++)
- {
- percent = (float)z / (float)(width - 1);
- float zBalance = CurvePoint(
- percent,
- (GetHeightOf(transform.position.x, transform.position.z - width) + myHeight) / 2,
- myHeight,
- (GetHeightOf(transform.position.x, transform.position.z + width) + myHeight) / 2);
- float finalHeight = (xBalance + zBalance) / 2;
- for (int y = 0; y < finalHeight; y++)
- {
- switch (biomeType)
- {
- default:
- if (y >= finalHeight - 1)
- map[x, y, z] = grassydirt;
- else
- map[x, y, z] = dirt;
- break;
- case BiomeType.Ice:
- if (y >= finalHeight - 1)
- map[x, y, z] = ice;
- else
- map[x, y, z] = dirt;
- break;
- case BiomeType.Desert:
- if (y >= finalHeight - 7)
- map[x, y, z] = sand;
- else
- map[x, y, z] = dirt;
- break;
- }
- }
- }
- }
- for (int dx = -1; dx <= 1; dx++)
- {
- for (int dz = -1; dz <= 1; dz++)
- {
- float myX = transform.position.x + dx * width;
- float myZ = transform.position.z + dz * width;
- List<LandBrush> brushes = GetBrushesFor(myX, myZ);
- for (int a = 0; a < brushes.Count; a++)
- {
- brushes[a].ApplyBrush(this);
- }
- }
- }
- initialized = true;
- Regenerate();
- }
- // Update is called once per frame
- void Update () {
- }
- public void CloseMeshTarget() {
- mesh.vertices = verts.ToArray();
- mesh.triangles = tris.ToArray();
- mesh.uv = uv.ToArray();
- mesh.RecalculateNormals();
- meshCollider.sharedMesh = mesh;
- }
- public void CreateMeshTarget(bool reset=false) {
- meshCollider = GetComponent<MeshCollider>();
- mesh = new Mesh();
- GetComponent<MeshFilter>().mesh = mesh;
- verts.Clear();
- tris.Clear();
- uv.Clear ();
- }
- public void DrawBrick(int x, int y, int z, byte block) {
- Vector3 start = new Vector3(x, y, z);
- Vector3 offset1, offset2;
- if (IsTransparent(x, y - 1, z))
- {
- offset1 = Vector3.left;
- offset2 = Vector3.back;
- DrawFace(start + Vector3.right, offset1, offset2, block);
- }
- if (IsTransparent(x, y + 1, z))
- {
- offset1 = Vector3.right;
- offset2 = Vector3.back;
- DrawFace(start + Vector3.up, offset1, offset2, block);
- }
- if (IsTransparent(x - 1, y, z))
- {
- offset1 = Vector3.back;
- offset2 = Vector3.down;
- DrawFace(start + Vector3.up, offset1, offset2, block);
- }
- if (IsTransparent(x + 1, y, z))
- {
- offset1 = Vector3.forward;
- offset2 = Vector3.down;
- DrawFace(start + Vector3.right + Vector3.up + Vector3.back, offset1, offset2, block);
- }
- if (IsTransparent(x, y, z - 1))
- {
- offset1 = Vector3.right;
- offset2 = Vector3.down;
- DrawFace(start + Vector3.back + Vector3.up, offset1, offset2, block);
- }
- if (IsTransparent(x, y, z + 1))
- {
- offset1 = Vector3.left;
- offset2 = Vector3.down;
- DrawFace(start + Vector3.up + Vector3.right, offset1, offset2, block);
- }
- }
- public void DrawFace(Vector3 start, Vector3 offset1, Vector3 offset2, byte block)
- {
- int index = verts.Count;
- verts.Add (start);
- verts.Add (start + offset1);
- verts.Add (start + offset2);
- verts.Add (start + offset1 + offset2);
- BlockType blockType = Terrain.blocks.GetBlock(block);
- Vector2 uvBase = blockType.UVCoord();
- float uvOff = 62f / 1024f;
- if ((offset1 == Vector3.right) && (offset2 == Vector3.back))
- {
- uv.Add (uvBase);
- uv.Add (uvBase + new Vector2(uvOff, 0));
- uv.Add (uvBase + new Vector2(0, -uvOff));
- uv.Add (uvBase + new Vector2(uvOff, -uvOff));
- }
- else
- {
- uv.Add (uvBase + new Vector2(0, -uvOff));
- uv.Add (uvBase + new Vector2(uvOff, -uvOff));
- uv.Add (uvBase + new Vector2(0, -uvOff * 2));
- uv.Add (uvBase + new Vector2(uvOff, -uvOff * 2));
- }
- tris.Add (index + 0);
- tris.Add (index + 1);
- tris.Add (index + 2);
- tris.Add (index + 3);
- tris.Add (index + 2);
- tris.Add (index + 1);
- }
- public bool IsTransparent(int x, int y, int z)
- {
- if(y< 0) return false;
- if ((x< 0) || (y < 0) || (z < 0) || (x >= width) || (y >= height) || (z >= width)) return true;
- return map[x,y,z] == 0;
- }
- public void Regenerate() {
- if (! initialized) return;
- CreateMeshTarget(true);
- mesh.triangles = tris.ToArray();
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- for (int z = 0; z < width; z++)
- {
- byte block = map[x,y,z];
- if (block == 0) continue;
- DrawBrick(x, y, z, block);
- }
- }
- }
- CloseMeshTarget();
- }
- public void SetBrick(int x, int y , int z, byte block)
- {
- if (y == 0) return;
- x -= Mathf.RoundToInt(transform.position.x);
- y -= Mathf.RoundToInt(transform.position.y);
- z -= Mathf.RoundToInt(transform.position.z);
- if ((x< 0) || (y < 0) || (z < 0) || (x >= width) || (y >= height) || (z >= width)) return;
- if (map[x,y,z] != block)
- {
- map[x,y,z] = block;
- Regenerate();
- }
- }
- public static List<LandBrush> GetBrushesFor(float x, float z) {
- List<LandBrush> brushes = new List<LandBrush>();
- Terrain terrain = Terrain.activeTerrain;
- TerrainType terrainType = GetTerrainFor(x, z);
- BiomeType biomeType = GetBiomeFor (x, z);
- Random.seed = terrain.seed + Mathf.FloorToInt(x * 7 + z * 13);
- float numBrushes = 8;
- if (terrainType == TerrainType.Mountains)
- numBrushes = 18;
- while (numBrushes > 0)
- {
- numBrushes--;
- brushes.Add (new LandBrush(x, z, terrain.chunkSize, terrainType, biomeType));
- }
- return brushes;
- }
- public static TerrainType GetTerrainFor(float x, float z) {
- Random.seed = Terrain.activeTerrain.seed + Mathf.FloorToInt(x * 7 + z * 13);
- return (TerrainType)Mathf.FloorToInt(Random.value * 3);
- }
- public static BiomeType GetBiomeFor (float x, float z) {
- x = Mathf.FloorToInt(x / 160);
- z = Mathf.FloorToInt(x / 160);
- Random.seed = Terrain.activeTerrain.seed + Mathf.FloorToInt(x * 7 + z * 13);
- return (BiomeType)Mathf.FloorToInt(Random.value * 4);
- }
- public static float GetHeightOf(float x, float z) {
- return GetHeightOf (GetTerrainFor(x, z));
- }
- public static float GetHeightOf(TerrainType terrainType) {
- switch (terrainType)
- {
- default: return 8;
- case TerrainType.Highlands:
- return 12;
- case TerrainType.Mountains:
- return 16;
- }
- }
- public static float CurvePoint(float percent, float val1, float val2, float val3)
- {
- float p1 = (1 - percent) * val1 + percent * val2;
- float p2 = (1 - percent) * val2 + percent * val3;
- return (1 - percent) * p1 + percent * p2;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment