Guest User

CHUNK

a guest
Sep 27th, 2013
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.39 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public enum TerrainType {
  6.     Lowlands,
  7.     Highlands,
  8.     Mountains
  9. }
  10.  
  11. public enum BiomeType {
  12.     Grasslands,
  13.     Forest,
  14.     Desert,
  15.     Ice
  16. }
  17.  
  18.  
  19. [RequireComponent (typeof(MeshFilter))]
  20. [RequireComponent (typeof(MeshCollider))]
  21. public class Chunk : MonoBehaviour {
  22.    
  23.    
  24.     public int height = 40;
  25.     public int groundHeight = 8;
  26.     public byte[,,] map;
  27.    
  28.     protected Mesh mesh;
  29.    
  30.     protected List<Vector3> verts = new List<Vector3>();
  31.     protected List<int> tris = new List<int>();
  32.     protected List<Vector2> uv = new List<Vector2>();
  33.    
  34.     protected MeshCollider meshCollider;
  35.    
  36.     public List<GameObject> targets = new List<GameObject>();
  37.    
  38.     protected bool initialized = false;
  39.     protected int width;
  40.    
  41.    
  42.     // Use this for initialization
  43.     void Start () {
  44.        
  45.         width = Terrain.activeTerrain.chunkSize;
  46.        
  47.         map = new byte[width, height, width];
  48.        
  49.        
  50.         TerrainType terrainType = GetTerrainFor(transform.position.x, transform.position.z);
  51.         BiomeType biomeType = GetBiomeFor(transform.position.x, transform.position.z);
  52.        
  53.         float myHeight = GetHeightOf(terrainType);
  54.        
  55.         byte dirt = Terrain.blocks.GetBlockByte("Dirt");
  56.         byte grassydirt = Terrain.blocks.GetBlockByte("GrassyDirt");
  57.         byte ice = Terrain.blocks.GetBlockByte("Ice");
  58.         byte sand = Terrain.blocks.GetBlockByte("Sand");
  59.        
  60.        
  61.         for (int x = 0; x < width; x++)
  62.         {
  63.             float percent = (float)x / (float)(width - 1);
  64.             float xBalance = CurvePoint(
  65.                 percent,
  66.                 (GetHeightOf(transform.position.x - width, transform.position.z) + myHeight) / 2,
  67.                 myHeight,
  68.                 (GetHeightOf(transform.position.x + width, transform.position.z) + myHeight) / 2);
  69.            
  70.             for (int z = 0; z < width; z++)
  71.             {
  72.                 percent = (float)z / (float)(width - 1);
  73.                 float zBalance = CurvePoint(
  74.                     percent,
  75.                     (GetHeightOf(transform.position.x, transform.position.z - width) + myHeight) / 2,
  76.                     myHeight,
  77.                     (GetHeightOf(transform.position.x, transform.position.z + width) + myHeight) / 2);
  78.                
  79.                
  80.                 float finalHeight = (xBalance + zBalance) / 2;
  81.                
  82.                 for (int y = 0; y < finalHeight; y++)
  83.                 {
  84.                     switch (biomeType)
  85.                     {
  86.                     default:
  87.                         if (y >= finalHeight - 1)
  88.                             map[x, y, z] = grassydirt;
  89.                         else
  90.                             map[x, y, z] = dirt;
  91.                         break;
  92.                     case BiomeType.Ice:
  93.                         if (y >= finalHeight - 1)
  94.                             map[x, y, z] = ice;
  95.                         else
  96.                             map[x, y, z] = dirt;
  97.                         break;
  98.                     case BiomeType.Desert:
  99.                         if (y >= finalHeight - 7)
  100.                             map[x, y, z] = sand;
  101.                         else
  102.                             map[x, y, z] = dirt;
  103.                         break;
  104.                        
  105.                     }
  106.                 }
  107.             }
  108.         }
  109.        
  110.         for (int dx = -1; dx <= 1; dx++)
  111.         {  
  112.             for (int dz = -1; dz <= 1; dz++)
  113.             {
  114.                 float myX = transform.position.x + dx * width;
  115.                 float myZ = transform.position.z + dz * width;
  116.                
  117.                 List<LandBrush> brushes = GetBrushesFor(myX, myZ);
  118.                 for (int a = 0; a < brushes.Count; a++)
  119.                 {
  120.                     brushes[a].ApplyBrush(this);
  121.                 }
  122.             }
  123.         }
  124.        
  125.         initialized = true;
  126.         Regenerate();
  127.        
  128.     }
  129.    
  130.     // Update is called once per frame
  131.     void Update () {
  132.     }
  133.    
  134.     public void CloseMeshTarget() {
  135.        
  136.         mesh.vertices = verts.ToArray();
  137.         mesh.triangles = tris.ToArray();
  138.         mesh.uv = uv.ToArray();
  139.         mesh.RecalculateNormals();
  140.        
  141.         meshCollider.sharedMesh = mesh;
  142.        
  143.     }
  144.    
  145.     public void CreateMeshTarget(bool reset=false) {
  146.        
  147.        
  148.         meshCollider = GetComponent<MeshCollider>();
  149.         mesh = new Mesh();
  150.         GetComponent<MeshFilter>().mesh = mesh;
  151.        
  152.        
  153.         verts.Clear();
  154.         tris.Clear();
  155.         uv.Clear ();
  156.        
  157.     }
  158.    
  159.     public void DrawBrick(int x, int y, int z, byte block)  {
  160.        
  161.         Vector3 start = new Vector3(x, y, z);
  162.         Vector3 offset1, offset2;
  163.        
  164.         if (IsTransparent(x, y - 1, z))
  165.         {
  166.             offset1 = Vector3.left;
  167.             offset2 = Vector3.back;
  168.             DrawFace(start + Vector3.right, offset1, offset2, block);
  169.         }
  170.        
  171.         if (IsTransparent(x, y + 1, z))
  172.         {
  173.             offset1 = Vector3.right;
  174.             offset2 = Vector3.back;
  175.             DrawFace(start + Vector3.up, offset1, offset2, block);
  176.         }
  177.        
  178.         if (IsTransparent(x - 1, y, z))
  179.         {
  180.             offset1 = Vector3.back;
  181.             offset2 = Vector3.down;
  182.             DrawFace(start + Vector3.up, offset1, offset2, block);
  183.         }
  184.        
  185.         if (IsTransparent(x + 1, y, z))
  186.         {
  187.             offset1 = Vector3.forward;
  188.             offset2 = Vector3.down;
  189.             DrawFace(start + Vector3.right + Vector3.up + Vector3.back, offset1, offset2, block);
  190.         }
  191.        
  192.        
  193.         if (IsTransparent(x, y, z - 1))
  194.         {
  195.             offset1 = Vector3.right;
  196.             offset2 = Vector3.down;
  197.             DrawFace(start + Vector3.back + Vector3.up, offset1, offset2, block);
  198.         }
  199.        
  200.        
  201.         if (IsTransparent(x, y, z + 1))
  202.         {
  203.             offset1 = Vector3.left;
  204.             offset2 = Vector3.down;
  205.             DrawFace(start + Vector3.up + Vector3.right, offset1, offset2, block);
  206.         }
  207.        
  208.        
  209.     }
  210.    
  211.    
  212.     public void DrawFace(Vector3 start, Vector3 offset1, Vector3 offset2, byte block)
  213.     {
  214.         int index = verts.Count;
  215.        
  216.         verts.Add (start);
  217.         verts.Add (start + offset1);
  218.         verts.Add (start + offset2);
  219.         verts.Add (start + offset1 + offset2);
  220.        
  221.         BlockType blockType = Terrain.blocks.GetBlock(block);
  222.         Vector2 uvBase = blockType.UVCoord();
  223.        
  224.         float uvOff = 62f / 1024f;
  225.        
  226.        
  227.         if ((offset1 == Vector3.right) && (offset2 == Vector3.back))
  228.         {
  229.             uv.Add (uvBase);
  230.             uv.Add (uvBase + new Vector2(uvOff, 0));
  231.             uv.Add (uvBase + new Vector2(0, -uvOff));
  232.             uv.Add (uvBase + new Vector2(uvOff, -uvOff));
  233.         }
  234.         else
  235.         {      
  236.             uv.Add (uvBase + new Vector2(0, -uvOff));
  237.             uv.Add (uvBase + new Vector2(uvOff, -uvOff));
  238.             uv.Add (uvBase + new Vector2(0, -uvOff * 2));
  239.             uv.Add (uvBase + new Vector2(uvOff, -uvOff * 2));
  240.         }
  241.        
  242.        
  243.        
  244.         tris.Add (index + 0);
  245.         tris.Add (index + 1);
  246.         tris.Add (index + 2);
  247.         tris.Add (index + 3);
  248.         tris.Add (index + 2);
  249.         tris.Add (index + 1);
  250.     }
  251.    
  252.     public bool IsTransparent(int x, int y, int z)
  253.     {
  254.        
  255.         if(y< 0) return false;
  256.        
  257.         if ((x< 0) || (y < 0) || (z < 0) || (x >= width) || (y >= height) || (z >= width)) return true;
  258.         return map[x,y,z] == 0;
  259.     }
  260.    
  261.     public void Regenerate() {
  262.         if (! initialized) return;
  263.        
  264.         CreateMeshTarget(true);
  265.        
  266.         mesh.triangles = tris.ToArray();
  267.        
  268.         for (int y = 0; y < height; y++)
  269.         {
  270.        
  271.             for (int x = 0; x < width; x++)
  272.             {
  273.                 for (int z = 0; z < width; z++)
  274.                 {
  275.                    
  276.                     byte block = map[x,y,z];
  277.                     if (block == 0) continue;
  278.                    
  279.                     DrawBrick(x, y, z, block);
  280.                    
  281.                 }
  282.             }
  283.         }
  284.        
  285.        
  286.         CloseMeshTarget();
  287.     }
  288.     public void SetBrick(int x, int y , int z, byte block)
  289.     {
  290.         if (y == 0) return;
  291.         x -= Mathf.RoundToInt(transform.position.x);
  292.         y -= Mathf.RoundToInt(transform.position.y);
  293.         z -= Mathf.RoundToInt(transform.position.z);
  294.        
  295.         if ((x< 0) || (y < 0) || (z < 0) || (x >= width) || (y >= height) || (z >= width)) return;
  296.        
  297.         if (map[x,y,z] != block)
  298.         {
  299.             map[x,y,z] = block;
  300.             Regenerate();
  301.         }
  302.     }
  303.    
  304.     public static List<LandBrush> GetBrushesFor(float x, float z) {
  305.         List<LandBrush> brushes = new List<LandBrush>();
  306.        
  307.         Terrain terrain = Terrain.activeTerrain;
  308.        
  309.         TerrainType terrainType = GetTerrainFor(x, z);
  310.         BiomeType biomeType = GetBiomeFor (x, z);
  311.        
  312.         Random.seed = terrain.seed + Mathf.FloorToInt(x * 7 + z * 13);
  313.        
  314.        
  315.         float numBrushes = 8;
  316.         if (terrainType == TerrainType.Mountains)
  317.             numBrushes = 18;
  318.         while (numBrushes > 0)
  319.         {
  320.             numBrushes--;
  321.             brushes.Add (new LandBrush(x, z, terrain.chunkSize, terrainType, biomeType));
  322.         }
  323.        
  324.         return brushes;
  325.     }
  326.    
  327.     public static TerrainType GetTerrainFor(float x, float z) {
  328.        
  329.         Random.seed = Terrain.activeTerrain.seed + Mathf.FloorToInt(x * 7 + z * 13);
  330.        
  331.         return (TerrainType)Mathf.FloorToInt(Random.value * 3);
  332.        
  333.     }
  334.     public static BiomeType GetBiomeFor (float x, float z) {
  335.        
  336.         x = Mathf.FloorToInt(x / 160);
  337.         z = Mathf.FloorToInt(x / 160);
  338.        
  339.         Random.seed = Terrain.activeTerrain.seed + Mathf.FloorToInt(x * 7 + z * 13);
  340.        
  341.         return (BiomeType)Mathf.FloorToInt(Random.value * 4);
  342.        
  343.     }
  344.    
  345.     public static float GetHeightOf(float x, float z) {
  346.         return GetHeightOf (GetTerrainFor(x, z));
  347.     }
  348.            
  349.     public static float GetHeightOf(TerrainType terrainType) {
  350.         switch (terrainType)
  351.         {
  352.         default: return 8;
  353.         case TerrainType.Highlands:
  354.             return 12;
  355.         case TerrainType.Mountains:
  356.             return 16;
  357.         }
  358.     }
  359.    
  360.     public static float CurvePoint(float percent, float val1, float val2, float val3)
  361.     {
  362.         float p1 = (1 - percent) * val1 + percent * val2;
  363.         float p2 = (1 - percent) * val2 + percent * val3;
  364.         return (1 - percent) * p1 + percent * p2;
  365.     }
  366.        
  367. }
Advertisement
Add Comment
Please, Sign In to add comment