using UnityEngine; /// /// Чистые данные чанка — без MonoBehaviour, без Unity-объектов. /// Легко сериализовать, передать в генератор, сохранить на диск. /// public class ChunkData { public const int SIZE = 16; // блоков по X и Z public const int HEIGHT = 16; // блоков по Y public readonly Vector3Int ChunkPos; // позиция чанка в чанковых координатах // null = пустой блок, иначе blockId private readonly string[,,] _blocks = new string[SIZE, HEIGHT, SIZE]; public bool IsDirty { get; private set; } = true; // нужен ли пересчёт меша public ChunkData(Vector3Int chunkPos) { ChunkPos = chunkPos; } /// Получить blockId по локальным координатам. null = пусто. public string GetBlock(int x, int y, int z) { if (!InBounds(x, y, z)) return null; return _blocks[x, y, z]; } public string GetBlock(Vector3Int local) => GetBlock(local.x, local.y, local.z); /// Установить блок. null = удалить. public void SetBlock(int x, int y, int z, string blockId) { if (!InBounds(x, y, z)) return; _blocks[x, y, z] = blockId; IsDirty = true; } public void SetBlock(Vector3Int local, string blockId) => SetBlock(local.x, local.y, local.z, blockId); public void ClearDirty() => IsDirty = false; public static bool InBounds(int x, int y, int z) => x >= 0 && x < SIZE && y >= 0 && y < HEIGHT && z >= 0 && z < SIZE; /// /// Перевод мировой позиции блока → позиция чанка (чанковые координаты). /// public static Vector3Int WorldToChunkPos(Vector3Int worldBlock) => new Vector3Int( Mathf.FloorToInt((float)worldBlock.x / SIZE), Mathf.FloorToInt((float)worldBlock.y / HEIGHT), Mathf.FloorToInt((float)worldBlock.z / SIZE)); /// /// Перевод мировой позиции блока → локальная позиция внутри чанка. /// public static Vector3Int WorldToLocal(Vector3Int worldBlock) { int x = worldBlock.x % SIZE; int y = worldBlock.y % HEIGHT; int z = worldBlock.z % SIZE; // Обработка отрицательных координат if (x < 0) x += SIZE; if (y < 0) y += HEIGHT; if (z < 0) z += SIZE; return new Vector3Int(x, y, z); } /// Позиция чанка → мировая позиция его нижнего-левого угла. public static Vector3Int ChunkToWorld(Vector3Int chunkPos) => new Vector3Int(chunkPos.x * SIZE, chunkPos.y * HEIGHT, chunkPos.z * SIZE); }