Advertisement
JontePonte

Shitty voxel engine

Jul 25th, 2024
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.80 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class ChunkGenerator : MonoBehaviour
  6. {
  7.     public int maxVoxelHeight;
  8.     public float amplitude;
  9.     public float frequency;
  10.  
  11.     public Texture2D atlas;
  12.  
  13.     Noise noise;
  14.     Vector3[][] faces;
  15.     Vector2[] uvCoords;
  16.     Vector3Int[] directions;
  17.     int[] voxelValues;
  18.  
  19.     List<Vector3> vertices = new List<Vector3>();
  20.     List<int> triangles = new List<int>();
  21.     List<Vector2> uvs = new List<Vector2>();
  22.  
  23.     private void Start()
  24.     {
  25.         Initialize();
  26.     }
  27.  
  28.     public Mesh CreateChunkMesh(Vector2Int offset)
  29.     {
  30.         Mesh mesh = new Mesh();
  31.         mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
  32.  
  33.         vertices.Clear();
  34.         triangles.Clear();
  35.         uvs.Clear();
  36.            
  37.         voxelValues = noise.GetVoxelValues(offset);
  38.  
  39.         //for (int i = 0; i < 256 * maxVoxelHeight; i++)
  40.         //{
  41.         //    if (voxelValues[i] == 1)
  42.         //    {
  43.         //        int z = i / (16 * maxVoxelHeight);
  44.         //        int remainderAfterZ = i % (16 * maxVoxelHeight);
  45.         //        int x = remainderAfterZ / maxVoxelHeight;
  46.         //        int y = remainderAfterZ % maxVoxelHeight;
  47.  
  48.         //        AddVoxel(new Vector3Int(x,y,z), i, vertices, triangles, uvs);
  49.         //    }
  50.         //}
  51.  
  52.         for (int z = 0, i = 0; z < 16; z++)
  53.         {
  54.             for (int x = 0; x < 16; x++)
  55.             {
  56.                 for (int y = 0; y < maxVoxelHeight; y++, i++)
  57.                 {
  58.                     if (voxelValues[i] == 1)
  59.                     {
  60.                         AddVoxel(new Vector3Int(x, y, z), i, vertices, triangles, uvs);
  61.                     }
  62.                 }
  63.             }
  64.         }
  65.        
  66.         mesh.vertices = vertices.ToArray();
  67.         mesh.triangles = triangles.ToArray();
  68.         mesh.uv = uvs.ToArray();
  69.  
  70.         return mesh;
  71.     }
  72.  
  73.     public GameObject CreateChunkObject(Vector2Int offset)
  74.     {
  75.         GameObject chunk = new GameObject();
  76.         chunk.name = "Chunk";
  77.         chunk.AddComponent<MeshRenderer>().material = new Material(Shader.Find("Unlit/Texture"));
  78.         chunk.GetComponent<MeshRenderer>().material.mainTexture = atlas;
  79.         chunk.AddComponent<MeshFilter>().mesh = CreateChunkMesh(offset);
  80.  
  81.         return chunk;
  82.     }
  83.  
  84.     private void AddVoxel(Vector3Int pos, int voxelIndex, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
  85.     {
  86.         for (int i = 0; i < 6; i++)
  87.         {
  88.             //Only add a face if it's visible
  89.             if (IsAirVoxel(pos, directions[i], voxelIndex))
  90.             {
  91.                 AddQuad(faces[i], pos, i, vertices, triangles, uvs);
  92.             }
  93.         }
  94.     }
  95.  
  96.     private void AddQuad(Vector3[] vertexPos, Vector3 quadPos, int i, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
  97.     {
  98.         int vertCount = vertices.Count;
  99.  
  100.         Vector2 bottomLeft = uvCoords[i];
  101.  
  102.         vertices.AddRange(new List<Vector3> {
  103.             vertexPos[0] + quadPos,
  104.             vertexPos[1] + quadPos,
  105.             vertexPos[2] + quadPos,
  106.             vertexPos[3] + quadPos });
  107.  
  108.         triangles.AddRange(new List<int> {
  109.             vertCount,
  110.             vertCount + 1,
  111.             vertCount + 3,
  112.             vertCount + 3,
  113.             vertCount + 1,
  114.             vertCount + 2 });
  115.  
  116.         uvs.AddRange(new List<Vector2> {
  117.             bottomLeft + new Vector2(.5f, 0),  
  118.             bottomLeft + new Vector2(.5f, .5f),
  119.             bottomLeft + new Vector2(0, .5f),
  120.             bottomLeft});
  121.     }
  122.  
  123.     bool IsAirVoxel(Vector3Int coord, Vector3Int offset, int i)
  124.     {
  125.         int x = coord.x + offset.x;
  126.         int y = coord.y + offset.y;
  127.         int z = coord.z + offset.z;
  128.  
  129.         bool xOutOfRange = x < 0 || x > 15;
  130.         bool yOutOfRange = y < 0 || y > maxVoxelHeight - 1;
  131.         bool zOutOfRange = z < 0 || z > 15;
  132.  
  133.         if (xOutOfRange || yOutOfRange || zOutOfRange)
  134.         {
  135.             return true;
  136.         }
  137.         int Index1D = x * (maxVoxelHeight * 16) + y * 16 + z;
  138.  
  139.         return voxelValues[Index1D] == 0;
  140.     }
  141.  
  142.  
  143.     private void Initialize()
  144.     {
  145.         noise = new Noise(maxVoxelHeight, amplitude, frequency);
  146.  
  147.         //The vertex positions for each face
  148.         faces = new Vector3[6][];
  149.  
  150.         // Bottom
  151.         faces[0] = new Vector3[] { new Vector3(1, 0, 0), new Vector3(1, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 0) };
  152.         // Front
  153.         faces[1] = new Vector3[] { new Vector3(1, 0, 1), new Vector3(1, 1, 1), new Vector3(0, 1, 1), new Vector3(0, 0, 1) };
  154.         // Back
  155.         faces[2] = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) };
  156.         // Left
  157.         faces[3] = new Vector3[] { new Vector3(0, 0, 1), new Vector3(0, 1, 1), new Vector3(0, 1, 0), new Vector3(0, 0, 0) };
  158.         // Right
  159.         faces[4] = new Vector3[] { new Vector3(1, 0, 0), new Vector3(1, 1, 0), new Vector3(1, 1, 1), new Vector3(1, 0, 1) };
  160.         // Top
  161.         faces[5] = new Vector3[] { new Vector3(0, 1, 0), new Vector3(0, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 0) };
  162.  
  163.         //The bottom left of each texture in the atlas
  164.         Vector2 topTex = Vector2.zero;
  165.         Vector2 sideTex = new Vector2(.5f, .5f);
  166.         Vector2 bottomTex = new Vector2(.5f, 0);
  167.  
  168.         uvCoords = new Vector2[]
  169.         {
  170.             bottomTex,
  171.             sideTex,
  172.             sideTex,
  173.             sideTex,
  174.             sideTex,
  175.             topTex
  176.         };
  177.  
  178.         directions = new Vector3Int[]
  179.         {
  180.             Vector3Int.down,
  181.             Vector3Int.forward,
  182.             Vector3Int.back,
  183.             Vector3Int.left,
  184.             Vector3Int.right,
  185.             Vector3Int.up,
  186.         };
  187.     }
  188. }
  189.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement