Files
my-project/Assets/Blocks/Scripts/ChunkData.cs
unknown 087db550f1 bloak
2026-04-16 18:19:23 +05:00

79 lines
3.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
/// <summary>
/// Чистые данные чанка — без MonoBehaviour, без Unity-объектов.
/// Легко сериализовать, передать в генератор, сохранить на диск.
/// </summary>
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;
}
/// <summary>Получить blockId по локальным координатам. null = пусто.</summary>
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);
/// <summary>Установить блок. null = удалить.</summary>
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;
/// <summary>
/// Перевод мировой позиции блока → позиция чанка (чанковые координаты).
/// </summary>
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));
/// <summary>
/// Перевод мировой позиции блока → локальная позиция внутри чанка.
/// </summary>
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);
}
/// <summary>Позиция чанка → мировая позиция его нижнего-левого угла.</summary>
public static Vector3Int ChunkToWorld(Vector3Int chunkPos) =>
new Vector3Int(chunkPos.x * SIZE, chunkPos.y * HEIGHT, chunkPos.z * SIZE);
}