bloak
This commit is contained in:
78
Assets/Blocks/Scripts/ChunkData.cs
Normal file
78
Assets/Blocks/Scripts/ChunkData.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user