지하 최적화
블록 프리팹 단위 -> 블록 청크 단위 스폰 기타 건설, 조준 관련 사이드이펙트 버그 수정
This commit is contained in:
215
Assets/Scripts/Underground/ChunkCoord.cs
Normal file
215
Assets/Scripts/Underground/ChunkCoord.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Utility struct for chunk coordinate conversions.
|
||||
/// Handles conversions between world, grid, chunk, and local block coordinates.
|
||||
/// </summary>
|
||||
public struct ChunkCoord
|
||||
{
|
||||
public const int CHUNK_SIZE = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Chunk position in chunk coordinates (not world or grid)
|
||||
/// </summary>
|
||||
public Vector3Int chunkPos;
|
||||
|
||||
public ChunkCoord(Vector3Int pos)
|
||||
{
|
||||
chunkPos = pos;
|
||||
}
|
||||
|
||||
public ChunkCoord(int x, int y, int z)
|
||||
{
|
||||
chunkPos = new Vector3Int(x, y, z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the grid position of the chunk's origin (corner with smallest coordinates)
|
||||
/// </summary>
|
||||
public Vector3Int GridOrigin => new Vector3Int(
|
||||
chunkPos.x * CHUNK_SIZE,
|
||||
chunkPos.y * CHUNK_SIZE,
|
||||
chunkPos.z * CHUNK_SIZE
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get world position of chunk origin using BuildManager's grid system
|
||||
/// </summary>
|
||||
public Vector3 WorldOrigin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BuildManager.Instance != null)
|
||||
{
|
||||
return BuildManager.Instance.GridToWorld(GridOrigin);
|
||||
}
|
||||
// Fallback if BuildManager not available
|
||||
return new Vector3(
|
||||
GridOrigin.x + 0.5f,
|
||||
GridOrigin.y + 0.5f,
|
||||
GridOrigin.z + 0.5f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert grid coordinates to chunk coordinates
|
||||
/// </summary>
|
||||
public static ChunkCoord FromGridPos(Vector3Int gridPos)
|
||||
{
|
||||
return new ChunkCoord(
|
||||
Mathf.FloorToInt((float)gridPos.x / CHUNK_SIZE),
|
||||
Mathf.FloorToInt((float)gridPos.y / CHUNK_SIZE),
|
||||
Mathf.FloorToInt((float)gridPos.z / CHUNK_SIZE)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert world position to chunk coordinates
|
||||
/// </summary>
|
||||
public static ChunkCoord FromWorldPos(Vector3 worldPos)
|
||||
{
|
||||
Vector3Int gridPos;
|
||||
if (BuildManager.Instance != null)
|
||||
{
|
||||
gridPos = BuildManager.Instance.WorldToGrid3D(worldPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback
|
||||
gridPos = new Vector3Int(
|
||||
Mathf.RoundToInt(worldPos.x - 0.5f),
|
||||
Mathf.RoundToInt(worldPos.y - 0.5f),
|
||||
Mathf.RoundToInt(worldPos.z - 0.5f)
|
||||
);
|
||||
}
|
||||
return FromGridPos(gridPos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get local block coordinates within chunk from grid position
|
||||
/// </summary>
|
||||
public static Vector3Int GridToLocal(Vector3Int gridPos)
|
||||
{
|
||||
// Use modulo to get local position, handling negative coords
|
||||
int x = ((gridPos.x % CHUNK_SIZE) + CHUNK_SIZE) % CHUNK_SIZE;
|
||||
int y = ((gridPos.y % CHUNK_SIZE) + CHUNK_SIZE) % CHUNK_SIZE;
|
||||
int z = ((gridPos.z % CHUNK_SIZE) + CHUNK_SIZE) % CHUNK_SIZE;
|
||||
return new Vector3Int(x, y, z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert local block coordinates to grid position
|
||||
/// </summary>
|
||||
public Vector3Int LocalToGrid(Vector3Int localPos)
|
||||
{
|
||||
return GridOrigin + localPos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert local block coordinates to world position
|
||||
/// </summary>
|
||||
public Vector3 LocalToWorld(Vector3Int localPos)
|
||||
{
|
||||
Vector3Int gridPos = LocalToGrid(localPos);
|
||||
if (BuildManager.Instance != null)
|
||||
{
|
||||
return BuildManager.Instance.GridToWorld(gridPos);
|
||||
}
|
||||
return new Vector3(gridPos.x + 0.5f, gridPos.y + 0.5f, gridPos.z + 0.5f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert local index to local 3D coordinates
|
||||
/// </summary>
|
||||
public static Vector3Int IndexToLocal(int index)
|
||||
{
|
||||
int x = index % CHUNK_SIZE;
|
||||
int y = (index / CHUNK_SIZE) % CHUNK_SIZE;
|
||||
int z = index / (CHUNK_SIZE * CHUNK_SIZE);
|
||||
return new Vector3Int(x, y, z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert local 3D coordinates to index
|
||||
/// </summary>
|
||||
public static int LocalToIndex(Vector3Int localPos)
|
||||
{
|
||||
return localPos.x + localPos.y * CHUNK_SIZE + localPos.z * CHUNK_SIZE * CHUNK_SIZE;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert local coordinates (int) to index
|
||||
/// </summary>
|
||||
public static int LocalToIndex(int x, int y, int z)
|
||||
{
|
||||
return x + y * CHUNK_SIZE + z * CHUNK_SIZE * CHUNK_SIZE;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if local coordinates are within valid range
|
||||
/// </summary>
|
||||
public static bool IsValidLocal(int x, int y, int z)
|
||||
{
|
||||
return x >= 0 && x < CHUNK_SIZE &&
|
||||
y >= 0 && y < CHUNK_SIZE &&
|
||||
z >= 0 && z < CHUNK_SIZE;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if local position is within valid range
|
||||
/// </summary>
|
||||
public static bool IsValidLocal(Vector3Int local)
|
||||
{
|
||||
return IsValidLocal(local.x, local.y, local.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert world hit point to local block index within chunk
|
||||
/// </summary>
|
||||
public int WorldPointToLocalIndex(Vector3 worldPoint)
|
||||
{
|
||||
// Get chunk origin in world space
|
||||
Vector3 chunkWorldOrigin = WorldOrigin;
|
||||
|
||||
// Calculate offset from chunk origin (in grid units, assuming 1 unit per block)
|
||||
float cellSize = BuildManager.Instance != null ? BuildManager.Instance.cellSize : 1f;
|
||||
Vector3 offset = (worldPoint - chunkWorldOrigin) / cellSize;
|
||||
|
||||
// Convert to local coordinates (add small epsilon to handle edge cases)
|
||||
int lx = Mathf.Clamp(Mathf.FloorToInt(offset.x + 0.5f), 0, CHUNK_SIZE - 1);
|
||||
int ly = Mathf.Clamp(Mathf.FloorToInt(offset.y + 0.5f), 0, CHUNK_SIZE - 1);
|
||||
int lz = Mathf.Clamp(Mathf.FloorToInt(offset.z + 0.5f), 0, CHUNK_SIZE - 1);
|
||||
|
||||
return LocalToIndex(lx, ly, lz);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ChunkCoord other)
|
||||
{
|
||||
return chunkPos == other.chunkPos;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return chunkPos.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(ChunkCoord a, ChunkCoord b)
|
||||
{
|
||||
return a.chunkPos == b.chunkPos;
|
||||
}
|
||||
|
||||
public static bool operator !=(ChunkCoord a, ChunkCoord b)
|
||||
{
|
||||
return a.chunkPos != b.chunkPos;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"ChunkCoord({chunkPos.x}, {chunkPos.y}, {chunkPos.z})";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user