Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using UnityEngine;
- public class ChunkGenerator : MonoBehaviour
- {
- public int maxVoxelHeight;
- public static int _maxVoxelHeight;
- public float amplitude;
- public float frequency;
- public Texture2D atlas;
- public string executionTime;
- Noise noise;
- Vector3[][] faces;
- Vector2[] uvCoords;
- Vector3Int[] directions;
- int[] voxelValues;
- private void Start()
- {
- Initialize();
- executionTime = "N/A";
- }
- public void GenerateChunk()
- {
- Initialize();
- float startTime = Time.realtimeSinceStartup;
- CreateChunkObject(Vector2Int.zero);
- executionTime = (Time.realtimeSinceStartup - startTime) * 1000f + " ms";
- }
- public Mesh CreateChunkMesh(Vector2Int offset)
- {
- Mesh mesh = new Mesh();
- mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
- List<Vector3> vertices = new List<Vector3>();
- List<int> triangles = new List<int>();
- List<Vector2> uvs = new List<Vector2>();
- voxelValues = noise.GetVoxelValues(offset);
- for (int i = 0; i < 256 * maxVoxelHeight; i++)
- {
- int x = i / (maxVoxelHeight * 16);
- int y = ((i % (maxVoxelHeight * 16))) / 16;
- int z = i % 16;
- if (voxelValues[GetVoxelIndex(x, y, z)] == 1)
- {
- AddVoxel(new Vector3Int(x, y, z), vertices, triangles, uvs);
- }
- }
- mesh.vertices = vertices.ToArray();
- mesh.triangles = triangles.ToArray();
- mesh.uv = uvs.ToArray();
- return mesh;
- }
- public GameObject CreateChunkObject(Vector2Int offset)
- {
- GameObject chunk = new GameObject();
- chunk.name = "Chunk";
- chunk.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Unlit/Texture"));
- chunk.GetComponent<MeshRenderer>().sharedMaterial.mainTexture = atlas;
- chunk.AddComponent<MeshFilter>().mesh = CreateChunkMesh(offset);
- return chunk;
- }
- private void AddVoxel(Vector3Int pos, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
- {
- for (int i = 0; i < 6; i++)
- {
- //Only add a face if it's visible
- if (IsAirVoxel(pos + directions[i]))
- {
- AddQuad(faces[i], pos, i, vertices, triangles, uvs);
- }
- }
- }
- private void AddQuad(Vector3[] vertexPos, Vector3 quadPos, int i, List<Vector3> vertices, List<int> triangles, List<Vector2> uvs)
- {
- int vertCount = vertices.Count;
- Vector2 bottomLeft = uvCoords[i];
- vertices.AddRange(new List<Vector3> {
- vertexPos[0] + quadPos,
- vertexPos[1] + quadPos,
- vertexPos[2] + quadPos,
- vertexPos[3] + quadPos });
- triangles.AddRange(new List<int> {
- vertCount,
- vertCount + 1,
- vertCount + 3,
- vertCount + 3,
- vertCount + 1,
- vertCount + 2 });
- uvs.AddRange(new List<Vector2> {
- bottomLeft + new Vector2(.5f, 0),
- bottomLeft + new Vector2(.5f, .5f),
- bottomLeft + new Vector2(0, .5f),
- bottomLeft});
- }
- bool IsAirVoxel(Vector3Int coord)
- {
- int x = coord.x;
- int y = coord.y;
- int z = coord.z;
- bool xOutOfRange = x < 0 || x > 15;
- bool yOutOfRange = y < 0 || y > _maxVoxelHeight - 1;
- bool zOutOfRange = z < 0 || z > 15;
- if (xOutOfRange || yOutOfRange || zOutOfRange)
- {
- return true;
- }
- return voxelValues[GetVoxelIndex(x,y,z)] == 0 ? true : false;
- }
- private void Initialize()
- {
- noise = new Noise(_maxVoxelHeight, amplitude, frequency);
- _maxVoxelHeight = maxVoxelHeight;
- //The vertex positions for each face
- faces = new Vector3[6][];
- // Bottom
- faces[0] = new Vector3[] { new Vector3(1, 0, 0), new Vector3(1, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 0) };
- // Front
- faces[1] = new Vector3[] { new Vector3(1, 0, 1), new Vector3(1, 1, 1), new Vector3(0, 1, 1), new Vector3(0, 0, 1) };
- // Back
- faces[2] = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) };
- // Left
- faces[3] = new Vector3[] { new Vector3(0, 0, 1), new Vector3(0, 1, 1), new Vector3(0, 1, 0), new Vector3(0, 0, 0) };
- // Right
- faces[4] = new Vector3[] { new Vector3(1, 0, 0), new Vector3(1, 1, 0), new Vector3(1, 1, 1), new Vector3(1, 0, 1) };
- // Top
- faces[5] = new Vector3[] { new Vector3(0, 1, 0), new Vector3(0, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 0) };
- //The bottom left of each texture in the atlas
- Vector2 topTex = Vector2.zero;
- Vector2 sideTex = new Vector2(.5f, .5f);
- Vector2 bottomTex = new Vector2(.5f, 0);
- uvCoords = new Vector2[]
- {
- bottomTex,
- sideTex,
- sideTex,
- sideTex,
- sideTex,
- topTex
- };
- directions = new Vector3Int[]
- {
- Vector3Int.down,
- Vector3Int.forward,
- Vector3Int.back,
- Vector3Int.left,
- Vector3Int.right,
- Vector3Int.up,
- };
- }
- public static int GetVoxelIndex(int x, int y, int z)
- {
- return x * (_maxVoxelHeight * 16) + y * 16 + z;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement