can you overhaul and optimize this code significantly? I need it to be nearly instant. give the full optimized and compacted code. try using multithreading and async as well. make sure you arent calling things that can only be called on the main thread on non-main threads

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;
using System.IO;
using System.Linq;
using System;

public class BlockFetcher : MonoBehaviour
{
    private string serverUrl = "http://localhost:8000/blocks";
    public string texturePath = "Assets/Textures";
    public Material blockMaterial;
    [Tooltip(
        "The name of the texture file to use when a block's texture is not found (without .png extension)"
    )]
    public string defaultTextureName = "missing_texture";
    private const int MAX_VERTICES_PER_CHUNK = 65000; // Slightly below Unity's limit of 65,535
    private List<MeshChunk> meshChunks = new List<MeshChunk>();

    public string[] woodTypes;
    public Mesh slabMesh;
    public Mesh fenceMesh;
    public Mesh stairMesh;

    private class MeshChunk
    {
        public List<Vector3> vertices;
        public List<int> triangles;
        public List<Vector2> uvs;
        public bool isFull => vertices.Count + 4 >= MAX_VERTICES_PER_CHUNK; // +4 for next quad

        public MeshChunk()
        {
            int capacity = MAX_VERTICES_PER_CHUNK + 4;
            vertices = new List<Vector3>(capacity);
            uvs = new List<Vector2>(capacity);
            triangles = new List<int>(capacity * 2); // Estimate triangle count
        }
    }

    [System.Serializable]
    public class BlockTextureConfig
    {
        public string blockName;
        public string top;
        public string bottom;
        public string front;
        public string back;
        public string left;
        public string right;
        public string side;
        public bool isBillboard;
        public Mesh customMesh;
        public void SetDefaults(string defaultName)
        {
            if (string.IsNullOrEmpty(top)) top = defaultName;
            if (string.IsNullOrEmpty(bottom)) bottom = defaultName;
            if (!string.IsNullOrEmpty(side))
            {
                front = back = left = right = side;
            }
            else
            {
                if (string.IsNullOrEmpty(front)) front = defaultName;
                if (string.IsNullOrEmpty(back)) back = defaultName;
                if (string.IsNullOrEmpty(left)) left = defaultName;
                if (string.IsNullOrEmpty(right)) right = defaultName;
            }
        }
    }

    [System.Serializable]
    public class BlockTintConfig
    {
        public string blockName;
        public Color tintColor;
        public string maskName;

        public BlockTintConfig(string blockName, Color tintColor, string maskName = null)
        {
            this.blockName = blockName;
            this.tintColor = tintColor;
            this.maskName = maskName;
        }
    }

    public BlockTextureConfig[] blockConfigs;
    public BlockTintConfig[] blockTintConfigs;

    private Texture2D textureAtlas;
    private List<BlockData> blockDataList;
    private Rect[] atlasRects;
    private Dictionary<string, int> blockNameToTextureIndex = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
    private Dictionary<string, BlockTextureConfig> blockConfigMap = new Dictionary<string, BlockTextureConfig>(StringComparer.OrdinalIgnoreCase);
    private int defaultTextureIndex;
    private Dictionary<int, Vector2[]> uvCache = new Dictionary<int, Vector2[]>();

    [System.Serializable]
    public class BlockData
    {
        public string block_name;
        public int x;
        public int y;
        public int z;
        public string direction;
    }

    private static readonly Vector3[,] faceVertices =
    {
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f),
            new Vector3(-0.5f,  0.5f, -0.5f)
        },
        {
            new Vector3(-0.5f, -0.5f, 0.5f),
            new Vector3( 0.5f, -0.5f, 0.5f),
            new Vector3( 0.5f,  0.5f, 0.5f),
            new Vector3(-0.5f,  0.5f, 0.5f)
        },
        {
            new Vector3(-0.5f,  0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f,  0.5f)
        },
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f,  0.5f),
            new Vector3(-0.5f, -0.5f,  0.5f)
        },
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3(-0.5f, -0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f, -0.5f)
        },
        {
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f,  0.5f),
            new Vector3( 0.5f,  0.5f,  0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f)
        }
    };

    private static readonly Vector3[][] billboardVertices = new Vector3[][]
    {
        new Vector3[]
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f,  0.5f),
            new Vector3( 0.5f,  0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f, -0.5f)
        },
        new Vector3[]
        {
            new Vector3(-0.5f, -0.5f,  0.5f),
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f),
            new Vector3(-0.5f,  0.5f,  0.5f)
        }
    };

    void Start()
    {
        InitializeBlockConfigs();
        CreateTextureAtlas();
        StartCoroutine(FetchBlocks());
    }

    private void InitializeBlockConfigs()
    {
        blockConfigMap.Clear();
        foreach (var config in blockConfigs)
        {
            config.SetDefaults(config.blockName);
            blockConfigMap[config.blockName] = config;
        }
    }

    private void CreateTextureAtlas()
    {
        string[] textureFiles = Directory.GetFiles(texturePath, "*.png");
        List<Texture2D> texturesList = new List<Texture2D>();
        Dictionary<string, Texture2D> maskTextures = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

        string maskPath = Path.Combine(texturePath, "Masks");
        if (Directory.Exists(maskPath))
        {
            foreach (string maskFile in Directory.GetFiles(maskPath, "*.png"))
            {
                string maskName = Path.GetFileNameWithoutExtension(maskFile);
                byte[] maskData = File.ReadAllBytes(maskFile);
                Texture2D maskTexture = new Texture2D(2, 2, TextureFormat.RGBA32, false);
                maskTexture.LoadImage(maskData);
                maskTextures[maskName] = maskTexture;
                Debug.Log($"Loaded mask texture: {maskName}");
            }
        }

        // Process default texture
        string defaultTexturePath = Path.Combine(texturePath, defaultTextureName + ".png");
        if (File.Exists(defaultTexturePath))
        {
            byte[] defaultTextureData = File.ReadAllBytes(defaultTexturePath);
            Texture2D defaultTexture = new Texture2D(2, 2, TextureFormat.RGBA32, false);
            defaultTexture.filterMode = FilterMode.Point;
            defaultTexture.LoadImage(defaultTextureData);
            texturesList.Add(defaultTexture);
            blockNameToTextureIndex[defaultTextureName] = 0;
            defaultTextureIndex = 0;
            Debug.Log($"Loaded default texture: {defaultTextureName} at index {defaultTextureIndex}");
        }
        else
        {
            Debug.LogError($"Default texture {defaultTexturePath} not found! Creating fallback texture.");
            Texture2D fallbackTexture = CreateFallbackTexture();
            texturesList.Add(fallbackTexture);
            defaultTextureIndex = 0;
        }

        // Process all other textures
        foreach (string textureFile in textureFiles)
        {
            string fileName = Path.GetFileNameWithoutExtension(textureFile);
            if (fileName.Equals(defaultTextureName, StringComparison.OrdinalIgnoreCase))
                continue; // Already processed default texture
            byte[] fileData = File.ReadAllBytes(textureFile);
            Texture2D texture = new Texture2D(2, 2, TextureFormat.RGBA32, false);
            texture.filterMode = FilterMode.Point;
            texture.LoadImage(fileData);

            foreach (var config in blockTintConfigs)
            {
                if (fileName.Equals(config.blockName, StringComparison.OrdinalIgnoreCase))
                {
                    Color[] pixels = texture.GetPixels();
                    Color[] maskPixels = null;
                    if (!string.IsNullOrEmpty(config.maskName) &&
                        maskTextures.TryGetValue(config.maskName, out Texture2D maskTexture))
                    {
                        if (maskTexture.width == texture.width && maskTexture.height == texture.height)
                        {
                            maskPixels = maskTexture.GetPixels();
                        }
                        else
                        {
                            Debug.LogWarning($"Mask texture {config.maskName} dimensions don't match block texture {fileName}");
                        }
                    }

                    for (int i = 0; i < pixels.Length; i++)
                    {
                        if (maskPixels != null)
                        {
                            float maskIntensity = maskPixels[i].grayscale;
                            pixels[i].r = Mathf.Lerp(pixels[i].r, pixels[i].r * config.tintColor.r, maskIntensity);
                            pixels[i].g = Mathf.Lerp(pixels[i].g, pixels[i].g * config.tintColor.g, maskIntensity);
                            pixels[i].b = Mathf.Lerp(pixels[i].b, pixels[i].b * config.tintColor.b, maskIntensity);
                        }
                        else
                        {
                            pixels[i].r *= config.tintColor.r;
                            pixels[i].g *= config.tintColor.g;
                            pixels[i].b *= config.tintColor.b;
                        }
                        pixels[i].r = Mathf.Clamp01(pixels[i].r);
                        pixels[i].g = Mathf.Clamp01(pixels[i].g);
                        pixels[i].b = Mathf.Clamp01(pixels[i].b);
                    }

                    texture.SetPixels(pixels);
                    texture.Apply();
                    break;
                }
            }

            int textureIndex = texturesList.Count;
            texturesList.Add(texture);
            blockNameToTextureIndex[fileName] = textureIndex;
            Debug.Log($"Mapped texture {fileName} to index {textureIndex}");
        }

        textureAtlas = new Texture2D(2048, 2048, TextureFormat.RGBA32, false);
        textureAtlas.filterMode = FilterMode.Point;
        atlasRects = textureAtlas.PackTextures(texturesList.ToArray(), 0, 2048);
        textureAtlas.Apply(false, true);
        blockMaterial.mainTexture = textureAtlas;
        blockMaterial.mainTexture.filterMode = FilterMode.Point;
        foreach (var maskTexture in maskTextures.Values)
        {
            UnityEngine.Object.Destroy(maskTexture);
        }
    }

    private Texture2D CreateFallbackTexture()
    {
        Texture2D fallback = new Texture2D(16, 16, TextureFormat.RGBA32, false);
        fallback.filterMode = FilterMode.Point;

        Color pink = new Color(1f, 0f, 1f, 1f);
        Color black = Color.black;

        for (int y = 0; y < 16; y++)
        {
            for (int x = 0; x < 16; x++)
            {
                Color color = ((x + y) % 2 == 0) ? pink : black;
                fallback.SetPixel(x, y, color);
            }
        }

        fallback.Apply();
        return fallback;
    }

    private int GetTextureIndexForTextureName(string textureName)
    {
        if (blockNameToTextureIndex.TryGetValue(textureName, out int textureIndex))
        {
            return textureIndex;
        }

        Debug.LogWarning($"No texture found for name: {textureName}. Using default texture.");
        return defaultTextureIndex;
    }

    private Vector2[] GetUVsForTexture(string textureName)
    {
        int textureIndex = GetTextureIndexForTextureName(textureName);

        if (textureIndex >= atlasRects.Length || textureIndex < 0)
        {
            Debug.LogError($"Invalid texture index: {textureIndex} for texture: {textureName}");
            textureIndex = defaultTextureIndex;
        }

        if (!uvCache.TryGetValue(textureIndex, out Vector2[] uvs))
        {
            Rect uvRect = atlasRects[textureIndex];
            uvs = new Vector2[]
            {
                new Vector2(uvRect.x, uvRect.y),
                new Vector2(uvRect.x + uvRect.width, uvRect.y),
                new Vector2(uvRect.x + uvRect.width, uvRect.y + uvRect.height),
                new Vector2(uvRect.x, uvRect.y + uvRect.height)
            };
            uvCache[textureIndex] = uvs;
        }
        return uvs;
    }

    private IEnumerator FetchBlocks()
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Get(serverUrl))
        {
            yield return webRequest.SendWebRequest();

            if (webRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError("Error fetching block data: " + webRequest.error);
            }
            else
            {
                string jsonResponse = webRequest.downloadHandler.text;
                blockDataList = JsonConvert.DeserializeObject<List<BlockData>>(jsonResponse);

                foreach (var block in blockDataList)
                {
                    AddBlockFaces(block);
                }

                CreateMesh();
            }
        }
    }

    private void AddBlockFaces(BlockData block)
    {
        Vector3 blockPosition = new Vector3(block.x, block.y, block.z);

        if (!blockConfigMap.TryGetValue(block.block_name, out BlockTextureConfig config))
        {
            config = new BlockTextureConfig { blockName = block.block_name };
            config.SetDefaults(block.block_name);
        }

        Dictionary<string, Mesh> customMeshes = new Dictionary<string, Mesh>
        {
            { "_slab", slabMesh },
            { "_fence", fenceMesh },
            { "_stairs", stairMesh }
        };
        string replace = null;
        string add = null;

        Mesh selectedMesh = config.customMesh;

        if (selectedMesh == null)
        {
            foreach (var kvp in customMeshes)
            {
                if (config.blockName.Contains(kvp.Key))
                {
                    selectedMesh = kvp.Value;
                    replace = kvp.Key;

                    if (woodTypes.Any(config.front.Contains))
                    {
                        add = "_planks";
                    }
                    break;
                }
            }
        }

        if (selectedMesh != null)
        {
            AddCustomMeshToChunk(blockPosition, selectedMesh, config.front, replace, add);
        }
        else if (config.isBillboard)
        {
            AddBillboardFacesToChunk(blockPosition, config);
        }
        else
        {
            AddDefaultCubeFacesToChunk(blockPosition, config);
        }
    }

    private void AddCustomMeshToChunk(
        Vector3 blockPosition,
        Mesh customMesh,
        string textureName,
        string replace,
        string add
    )
    {
        if (replace != null)
        {
            textureName = textureName.Replace(replace, "") + add;
        }

        MeshChunk chunk = GetCurrentChunk();
        Vector2[] textureUVs = GetUVsForTexture(textureName);
        int vertCount = chunk.vertices.Count;

        Vector3[] vertices = customMesh.vertices;
        int[] triangles = customMesh.triangles;
        int vertexCount = vertices.Length;

        for (int i = 0; i < vertexCount; i++)
        {
            chunk.vertices.Add(vertices[i] + blockPosition);
            chunk.uvs.Add(textureUVs[i % 4]);
        }

        for (int i = 0; i < triangles.Length; i++)
        {
            chunk.triangles.Add(vertCount + triangles[i]);
        }
    }

    private MeshChunk GetCurrentChunk()
    {
        if (meshChunks.Count == 0 || meshChunks[meshChunks.Count - 1].isFull)
        {
            meshChunks.Add(new MeshChunk());
        }
        return meshChunks[meshChunks.Count - 1];
    }

    private void AddBillboardFacesToChunk(Vector3 blockPosition, BlockTextureConfig config)
    {
        Vector2[] textureUVs = GetUVsForTexture(config.front);

        for (int planeIndex = 0; planeIndex < 2; planeIndex++)
        {
            MeshChunk chunk = GetCurrentChunk();
            int vertCount = chunk.vertices.Count;

            for (int i = 0; i < 4; i++)
            {
                chunk.vertices.Add(billboardVertices[planeIndex][i] + blockPosition);
                chunk.uvs.Add(textureUVs[i]);
            }

            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 1);
            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 3);
            chunk.triangles.Add(vertCount + 2);

            chunk = GetCurrentChunk();
            vertCount = chunk.vertices.Count;

            for (int i = 0; i < 4; i++)
            {
                chunk.vertices.Add(billboardVertices[planeIndex][i] + blockPosition);
                chunk.uvs.Add(textureUVs[i]);
            }

            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 1);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 3);
        }
    }

    private void AddDefaultCubeFacesToChunk(Vector3 blockPosition, BlockTextureConfig config)
    {
        string[] faceTextures = new string[]
        {
            config.front,
            config.back,
            config.top,
            config.bottom,
            config.left,
            config.right
        };

        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
        {
            MeshChunk chunk = GetCurrentChunk();
            Vector2[] textureUVs = GetUVsForTexture(faceTextures[faceIndex]);
            int vertCount = chunk.vertices.Count;

            for (int i = 0; i < 4; i++)
            {
                chunk.vertices.Add(faceVertices[faceIndex, i] + blockPosition);
                chunk.uvs.Add(textureUVs[i]);
            }

            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 1);
            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 3);
            chunk.triangles.Add(vertCount + 2);
        }
    }

    private void CreateMesh()
    {
        GameObject chunksParent = new GameObject("ChunkedMeshes");
        chunksParent.transform.position = Vector3.zero;

        for (int i = 0; i < meshChunks.Count; i++)
        {
            MeshChunk chunk = meshChunks[i];
            GameObject chunkObject = new GameObject($"MeshChunk_{i}");
            chunkObject.transform.parent = chunksParent.transform;
            chunkObject.transform.localPosition = Vector3.zero;

            MeshFilter meshFilter = chunkObject.AddComponent<MeshFilter>();
            MeshRenderer meshRenderer = chunkObject.AddComponent<MeshRenderer>();
            Mesh mesh = new Mesh();
            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

            mesh.SetVertices(chunk.vertices);
            mesh.SetTriangles(chunk.triangles, 0);
            mesh.SetUVs(0, chunk.uvs);

            mesh.RecalculateNormals();

            meshFilter.mesh = mesh;
            meshRenderer.material = blockMaterial;

            chunkObject.AddComponent<MeshCollider>().sharedMesh = mesh;
        }

        Debug.Log($"Created {meshChunks.Count} mesh chunks");
    }
}