Advertisement
Guest User

Untitled

a guest
Oct 27th, 2017
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.68 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class Chunk : MonoBehaviour {
  6.  
  7.     public const int chunkStack = 10;
  8.     public const int width = 16, height = 25;
  9.  
  10.     public static Dictionary<Vector3, Chunk> chunks = new Dictionary<Vector3, Chunk>();
  11.     public static bool Working = false;
  12.  
  13.     public List<byte[,,]> maps = new List<byte[,,]>();
  14.     public List<MeshFilter> meshes = new List<MeshFilter>();
  15.     public List<MeshCollider> colliders = new List<MeshCollider>();
  16.  
  17.     public List<List<Vector3>> verts = new List<List<Vector3>>();
  18.     public List<List<int>> triangles = new List<List<int>>();
  19.     public List<List<Vector2>> uvs = new List<List<Vector2>>();
  20.     public List<List<Color>> colors = new List<List<Color>>();
  21.  
  22.     public byte[,,] map = new byte[width,height,width];
  23.     public byte[,] heightMap = new byte[width,width];
  24.  
  25.     public bool dirty = true;
  26.     public bool lightDirty = true;
  27.     public bool calculateMap = false;
  28.  
  29.     public Vector3 chunkPos;
  30.     public bool canGenerateMesh = false;
  31.  
  32.     void Awake ()
  33.     {
  34.         transform.parent = World.me;
  35.  
  36.         for(int i = 0; i < chunkStack; i++)
  37.         {
  38.             maps.Add(new byte[width,height,width]);
  39.             GameObject go = new GameObject("ChunkStack " + i);
  40.  
  41.             colliders.Add(go.AddComponent<MeshCollider>());
  42.             meshes.Add(go.AddComponent<MeshFilter>());
  43.             MeshRenderer me = go.AddComponent<MeshRenderer>();
  44.  
  45.             go.transform.position = new Vector3(transform.position.x, i * height, transform.position.z);
  46.             go.transform.parent = transform;
  47.  
  48.             me.material = World.mats;
  49.         }
  50.  
  51.         heightMap = (new byte[width,width]);
  52.     }
  53.  
  54.     void Update ()
  55.     {
  56.         if(canGenerateMesh) return;
  57.  
  58.         Chunk right = GetChunk(chunkPos + new Vector3(width, 0, 0));
  59.         Chunk left = GetChunk(chunkPos + new Vector3(-width, 0, 0));
  60.  
  61.         Chunk back = GetChunk(chunkPos + new Vector3(0, 0, width));
  62.         Chunk front = GetChunk(chunkPos + new Vector3(0, 0, -width));
  63.  
  64.         Chunk up = GetChunk(chunkPos + new Vector3(0 , height, 0));
  65.         Chunk down = GetChunk(chunkPos + new Vector3(0, -height, 0));
  66.  
  67.         if(right != null && right.calculateMap &&
  68.             left != null && left.calculateMap &&
  69.             front != null && front.calculateMap &&
  70.             back != null && back.calculateMap &&
  71.             up != null && up.calculateMap &&
  72.             down != null && down.calculateMap)
  73.         {
  74.             canGenerateMesh = true;
  75.         }
  76.     }
  77.  
  78.     public void CMap()
  79.     {
  80.         Working = false;
  81.  
  82.         System.Random r = new System.Random();
  83.  
  84.         for(int i = 0; i < chunkStack; i++)
  85.         {
  86.             byte[,,] map = new byte[width, height, width];
  87.  
  88.             for(int x = 0; x < width; x++)
  89.             {
  90.                 for(int y = 0; y < height; y++)
  91.                 {
  92.                     for(int z = 0; z < width; z++)
  93.                     {
  94.                         int worldYPos = (i * height) + y;
  95.  
  96.                         if(worldYPos == height)
  97.                         {
  98.                             SetWorldBlock(chunkPos + new Vector3(x,y,z), 4);
  99.                         }
  100.                         else if(worldYPos < height + 5)
  101.                         {
  102.                             //map[x,y,z] = 1;
  103.                             SetWorldBlock(chunkPos + new Vector3(x,y,z), 1);
  104.                         }
  105.                         else if(worldYPos == height + 5 && r.Next(0,25) == 1)
  106.                         {
  107.                             SetWorldBlock(chunkPos + new Vector3(x,y,z), 3);
  108.                         }
  109.                     }
  110.                 }
  111.             }
  112.  
  113.             maps[i] = map;
  114.         }
  115.     }
  116.  
  117.     public void CMesh()
  118.     {
  119.         verts.Clear();
  120.         triangles.Clear();
  121.         uvs.Clear();
  122.         colors.Clear();
  123.  
  124.         for(int i = 0; i < chunkStack; i++)
  125.         {
  126.             byte[,,] map = maps[i];
  127.  
  128.             for(int x = 0; x < width; x++)
  129.             {
  130.                 for(int y = 0; y < height; y++)
  131.                 {
  132.                     for(int z = 0; z < width; z++)
  133.                     {
  134.                         if(map[x,y,z] > 0)
  135.                         {
  136.                             if(isBlockTransparent(x, y + 1, z, i))
  137.                                 AddFace(x, y, z, FaceDir.Top, i);
  138.                             if(isBlockTransparent(x, y - 1, z, i))
  139.                                 AddFace(x, y, z, FaceDir.Bottom, i);
  140.                             if(isBlockTransparent(x + 1, y, z, i))
  141.                                 AddFace(x, y, z, FaceDir.Right, i);
  142.                             if(isBlockTransparent(x - 1, y, z, i))
  143.                                 AddFace(x, y, z, FaceDir.Left, i);
  144.                             if(isBlockTransparent(x, y, z + 1, i))
  145.                                 AddFace(x, y, z, FaceDir.Front, i);
  146.                             if(isBlockTransparent(x, y, z - 1, i))
  147.                                 AddFace(x, y, z, FaceDir.Back, i);
  148.                         }
  149.                     }
  150.                 }
  151.             }
  152.  
  153.             if(verts.Count <= i) continue;
  154.             Mesh m = new Mesh();
  155.  
  156.             m.vertices = verts[i].ToArray();
  157.             m.triangles = triangles[i].ToArray();
  158.             m.uv = uvs[i].ToArray();
  159.             m.colors = colors[i].ToArray();
  160.  
  161.             m.RecalculateNormals();
  162.  
  163.             meshes[i].mesh = m;
  164.             colliders[i].sharedMesh = m;
  165.         }
  166.  
  167.         Working = false;
  168.     }
  169.  
  170.     public void CLight()
  171.     {
  172.         Working = false;
  173.     }
  174.  
  175.     public void AddFace (int x, int y, int z, FaceDir dir, int chunkID)
  176.     {
  177.         if(verts.Count >= chunkID)
  178.         {
  179.             verts.Add(new List<Vector3>());
  180.         }
  181.         if(triangles.Count >= chunkID)
  182.         {
  183.             triangles.Add(new List<int>());
  184.         }
  185.         if(uvs.Count >= chunkID)
  186.         {
  187.             uvs.Add(new List<Vector2>());
  188.         }
  189.         if(colors.Count >= chunkID)
  190.         {
  191.             colors.Add(new List<Color>());
  192.         }
  193.  
  194.         float blockWidth = (float)1 / (float)16;
  195.  
  196.         byte blockID = (byte)(maps[chunkID][x,y,z] - 1);
  197.  
  198.         int xOffset = Block.blocks[blockID].textureXSide;
  199.         int yOffset = Block.blocks[blockID].textureYSide;
  200.  
  201.         int BxOffset = Block.blocks[blockID].textureXBottom;
  202.         int ByOffset = Block.blocks[blockID].textureYBottom;
  203.  
  204.         int TxOffset = Block.blocks[blockID].textureXTop;
  205.         int TyOffset = Block.blocks[blockID].textureYTop;
  206.  
  207.         /*if(chunkPos.y + y < heightMap[x,z])
  208.         {
  209.             colors[chunkID].Add(Color.red);
  210.             colors[chunkID].Add(Color.red);
  211.             colors[chunkID].Add(Color.red);
  212.             colors[chunkID].Add(Color.red);
  213.         }
  214.         else
  215.         {
  216.             colors[chunkID].Add(Color.white);
  217.             colors[chunkID].Add(Color.white);
  218.             colors[chunkID].Add(Color.white);
  219.             colors[chunkID].Add(Color.white);
  220.         }*/
  221.  
  222.         colors[chunkID].Add(Color.white);
  223.         colors[chunkID].Add(Color.white);
  224.         colors[chunkID].Add(Color.white);
  225.         colors[chunkID].Add(Color.white);
  226.  
  227.  
  228.         if(dir == FaceDir.Top)
  229.         {
  230.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  231.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  232.             triangles[chunkID].Add(verts[chunkID].Count + 1);
  233.  
  234.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  235.             triangles[chunkID].Add(verts[chunkID].Count + 3);
  236.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  237.  
  238.             verts[chunkID].Add((new Vector3(x + 0, y + 1, z + 0)));
  239.             verts[chunkID].Add((new Vector3(x + 1, y + 1, z + 0)));
  240.             verts[chunkID].Add((new Vector3(x + 1, y + 1, z + 1)));
  241.             verts[chunkID].Add((new Vector3(x + 0, y + 1, z + 1)));
  242.  
  243.             uvs[chunkID].Add(new Vector2((0 + TxOffset) * blockWidth, (0 + TyOffset) * blockWidth));
  244.             uvs[chunkID].Add(new Vector2((1 + TxOffset) * blockWidth, (0 + TyOffset) * blockWidth));
  245.             uvs[chunkID].Add(new Vector2((1 + TxOffset) * blockWidth, (1 + TyOffset) * blockWidth));
  246.             uvs[chunkID].Add(new Vector2((0 + TxOffset) * blockWidth, (1 + TyOffset) * blockWidth));
  247.         }
  248.         else if(dir == FaceDir.Bottom)
  249.         {
  250.             triangles[chunkID].Add(verts[chunkID].Count + 1);
  251.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  252.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  253.  
  254.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  255.             triangles[chunkID].Add(verts[chunkID].Count + 3);
  256.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  257.  
  258.             verts[chunkID].Add((new Vector3(x + 0, y + 0, z + 0)));
  259.             verts[chunkID].Add((new Vector3(x + 1, y + 0, z + 0)));
  260.             verts[chunkID].Add((new Vector3(x + 1, y + 0, z + 1)));
  261.             verts[chunkID].Add((new Vector3(x + 0, y + 0, z + 1)));
  262.  
  263.             uvs[chunkID].Add(new Vector2((0 + BxOffset) * blockWidth, (0 + ByOffset) * blockWidth));
  264.             uvs[chunkID].Add(new Vector2((1 + BxOffset) * blockWidth, (0 + ByOffset) * blockWidth));
  265.             uvs[chunkID].Add(new Vector2((1 + BxOffset) * blockWidth, (1 + ByOffset) * blockWidth));
  266.             uvs[chunkID].Add(new Vector2((0 + BxOffset) * blockWidth, (1 + ByOffset) * blockWidth));
  267.         }
  268.         else if(dir == FaceDir.Front)
  269.         {
  270.             triangles[chunkID].Add(verts[chunkID].Count + 1);
  271.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  272.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  273.  
  274.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  275.             triangles[chunkID].Add(verts[chunkID].Count + 3);
  276.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  277.  
  278.             verts[chunkID].Add((new Vector3(x + 0, y + 0, z + 1)));
  279.             verts[chunkID].Add((new Vector3(x + 1, y + 0, z + 1)));
  280.             verts[chunkID].Add((new Vector3(x + 1, y + 1, z + 1)));
  281.             verts[chunkID].Add((new Vector3(x + 0, y + 1, z + 1)));
  282.  
  283.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  284.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  285.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  286.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  287.         }
  288.         else if(dir == FaceDir.Back)
  289.         {
  290.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  291.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  292.             triangles[chunkID].Add(verts[chunkID].Count + 1);
  293.  
  294.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  295.             triangles[chunkID].Add(verts[chunkID].Count + 3);
  296.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  297.  
  298.             verts[chunkID].Add((new Vector3(x + 0, y + 0, z + 0)));
  299.             verts[chunkID].Add((new Vector3(x + 1, y + 0, z + 0)));
  300.             verts[chunkID].Add((new Vector3(x + 1, y + 1, z + 0)));
  301.             verts[chunkID].Add((new Vector3(x + 0, y + 1, z + 0)));
  302.  
  303.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  304.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  305.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  306.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  307.         }
  308.         else if(dir == FaceDir.Right)
  309.         {
  310.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  311.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  312.             triangles[chunkID].Add(verts[chunkID].Count + 1);
  313.  
  314.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  315.             triangles[chunkID].Add(verts[chunkID].Count + 3);
  316.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  317.  
  318.             verts[chunkID].Add((new Vector3(x + 1, y + 0, z + 0)));
  319.             verts[chunkID].Add((new Vector3(x + 1, y + 0, z + 1)));
  320.             verts[chunkID].Add((new Vector3(x + 1, y + 1, z + 1)));
  321.             verts[chunkID].Add((new Vector3(x + 1, y + 1, z + 0)));
  322.  
  323.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  324.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  325.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  326.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  327.         }
  328.         else if(dir == FaceDir.Left)
  329.         {
  330.             triangles[chunkID].Add(verts[chunkID].Count + 1);
  331.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  332.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  333.  
  334.             triangles[chunkID].Add(verts[chunkID].Count + 2);
  335.             triangles[chunkID].Add(verts[chunkID].Count + 3);
  336.             triangles[chunkID].Add(verts[chunkID].Count + 0);
  337.  
  338.             verts[chunkID].Add((new Vector3(x + 0, y + 0, z + 0)));
  339.             verts[chunkID].Add((new Vector3(x + 0, y + 0, z + 1)));
  340.             verts[chunkID].Add((new Vector3(x + 0, y + 1, z + 1)));
  341.             verts[chunkID].Add((new Vector3(x + 0, y + 1, z + 0)));
  342.  
  343.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  344.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (0 + yOffset) * blockWidth));
  345.             uvs[chunkID].Add(new Vector2((1 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  346.             uvs[chunkID].Add(new Vector2((0 + xOffset) * blockWidth, (1 + yOffset) * blockWidth));
  347.         }
  348.     }
  349.  
  350.     public bool isBlockTransparent(int x, int y, int z, int chunkID)
  351.     {
  352.         if(x >= width || z >= width || y >= height || x < 0 || y < 0 || z < 0)
  353.         {
  354.             //return true;
  355.             return GetWorldBlock(new Vector3(x,y + (chunkID * height), z) + chunkPos) == 0;
  356.         }
  357.         else
  358.         {
  359.             return(maps[chunkID][x,y,z] == 0);
  360.         }
  361.     }
  362.  
  363.     public static byte GetWorldBlock(Vector3 pos)
  364.     {
  365.         Chunk c = Chunk.GetChunk(pos);
  366.         if(c == null) return 1;
  367.  
  368.         Vector3 localPos = pos - c.chunkPos;
  369.  
  370.         int chunkID = Mathf.FloorToInt(localPos.y / height);
  371.  
  372.         int x = (int)localPos.x;
  373.         int y = (int)localPos.y - (chunkID * height);
  374.         int z = (int)localPos.z;
  375.  
  376.         if (chunkID > 9 || chunkID < 0 || x < 0 || y < 0 || z < 0 || x > 15 || y > 15 || z > 15)
  377.         {
  378.             return 0;
  379.         }
  380.         else
  381.         {
  382.             byte block = c.maps[chunkID][x, y, z];
  383.             return block;
  384.         }
  385.     }
  386.  
  387.     public static Chunk SetWorldBlock(Vector3 pos, byte blockID)
  388.     {
  389.         Chunk c = Chunk.GetChunk(pos);
  390.         if(c == null) return null;
  391.  
  392.         Vector3 localPos = pos - c.chunkPos;
  393.  
  394.         int chunkID = Mathf.FloorToInt(localPos.y / height);
  395.  
  396.         if(chunkID >= chunkStack || chunkID < 0)
  397.             return null;
  398.  
  399.         int x = (int)localPos.x;
  400.         int y = (int)localPos.y - (chunkID * height);
  401.         int z = (int)localPos.z;
  402.  
  403.         int worldY = ((chunkID * height) + y);
  404.  
  405.         c.maps[chunkID][x,y,z] = blockID;
  406.  
  407.         /*if(c.heightMap[x,z] < worldY)
  408.         {
  409.             c.heightMap[x,z] = (byte)worldY;
  410.         }*/
  411.         return c;
  412.     }
  413.  
  414.     public static Chunk GetChunk(Vector3 pos)
  415.     {
  416.         int x = Mathf.FloorToInt(pos.x / width) * width;
  417.         int y = 0;
  418.         int z = Mathf.FloorToInt(pos.z / width) * width;
  419.  
  420.         Vector3 cPos = new Vector3(x, y, z);
  421.         if(chunks.ContainsKey(cPos))
  422.         {
  423.             return chunks[cPos];
  424.         }
  425.  
  426.         return null;
  427.     }
  428.  
  429.     public static bool ChunkExists(Vector3 pos)
  430.     {
  431.         int x = Mathf.FloorToInt(pos.x / width) * width;
  432.         int y = 0;
  433.         int z = Mathf.FloorToInt(pos.z / width) * width;
  434.  
  435.         Vector3 cPos = new Vector3(x, y, z);
  436.         if(chunks.ContainsKey(cPos))
  437.         {
  438.             return true;
  439.         }
  440.  
  441.         return false;
  442.     }
  443.  
  444.     public static bool AddChunk(Vector3 pos)
  445.     {
  446.         int x = Mathf.FloorToInt(pos.x / width) * width;
  447.         int y = Mathf.FloorToInt(pos.y / width) * width;
  448.         int z = Mathf.FloorToInt(pos.z / width) * width;
  449.  
  450.         Vector3 cPos = new Vector3(x, y, z);
  451.         if(chunks.ContainsKey(cPos))
  452.         {
  453.             return false;
  454.         }
  455.  
  456.         GameObject chunk = new GameObject("Chunk" + cPos);
  457.  
  458.         Chunk c = chunk.AddComponent<Chunk>();
  459.         MeshRenderer mr = chunk.AddComponent<MeshRenderer>();
  460.         chunk.AddComponent<MeshFilter>();
  461.  
  462.         chunk.transform.position = cPos;
  463.  
  464.         mr.material = World.mats;
  465.  
  466.         chunks.Add(cPos, c);
  467.         return true;
  468.     }
  469.     public static bool RemoveChunk(Vector3 pos)
  470.     {
  471.         int x = Mathf.FloorToInt(pos.x / width) * width;
  472.         int y = Mathf.FloorToInt(pos.y / width) * width;
  473.         int z = Mathf.FloorToInt(pos.z / width) * width;
  474.  
  475.         Vector3 cPos = new Vector3(x, y, z);
  476.         if(chunks.ContainsKey(cPos))
  477.         {
  478.             Destroy(chunks[cPos].gameObject);
  479.             chunks.Remove(cPos);
  480.             return true;
  481.         }
  482.         return false;
  483.     }
  484. }
  485.  
  486. public enum FaceDir
  487. {
  488.     Top,
  489.     Bottom,
  490.     Right,
  491.     Left,
  492.     Front,
  493.     Back,
  494. }
  495.  
  496. public class Block
  497. {
  498.     public static List<Block> blocks = new List<Block>();
  499.     public string displayName;
  500.     public string name;
  501.     public byte id;
  502.  
  503.     public byte textureXSide;
  504.     public byte textureYSide;
  505.  
  506.     public byte textureXTop;
  507.     public byte textureYTop;
  508.  
  509.     public byte textureXBottom;
  510.     public byte textureYBottom;
  511.  
  512.     public Block (string name, string displayName, byte tX, byte tY)
  513.     {
  514.         id = (byte)(blocks.Count + 1);
  515.         this.name = name;
  516.         this.displayName = displayName;
  517.  
  518.         textureXSide = tX;
  519.         textureXTop = tX;
  520.         textureXBottom = tX;
  521.  
  522.         textureYSide = tY;
  523.         textureYTop = tY;
  524.         textureYBottom = tY;
  525.     }
  526.  
  527.     public Block (string name, string displayName, byte tX, byte tY, byte sX, byte sY)
  528.     {
  529.         id = (byte)(blocks.Count + 1);
  530.         this.name = name;
  531.         this.displayName = displayName;
  532.  
  533.         textureXSide = sX;
  534.         textureXTop = tX;
  535.         textureXBottom = tX;
  536.  
  537.         textureYSide = sY;
  538.         textureYTop = tY;
  539.         textureYBottom = tY;
  540.     }
  541.  
  542.     public Block (string name, string displayName, byte tX, byte tY, byte sX, byte sY, byte bX, byte bY)
  543.     {
  544.         id = (byte)(blocks.Count + 1);
  545.         this.name = name;
  546.         this.displayName = displayName;
  547.  
  548.         textureXSide = sX;
  549.         textureXTop = tX;
  550.         textureXBottom = bX;
  551.  
  552.         textureYSide = sY;
  553.         textureYTop = tY;
  554.         textureYBottom = bY;
  555.     }
  556. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement