[Fix] Chunk Unload #2

Merged
horooko merged 1 commits from feature/ChunkUnload into master 2026-04-07 00:35:11 +03:00
@@ -281,9 +281,11 @@ namespace InfiniteWorld.VoxelWorld
continue;
}
Vector2Int regionCoord = ChunkToRegion(coord);
MarkRegionDirty(coord);
chunks.Remove(coord);
runtime.Dispose();
TryDisposeRegionIfEmpty(regionCoord);
QueueNeighborRefresh(coord);
}
}
@@ -510,7 +512,16 @@ namespace InfiniteWorld.VoxelWorld
continue;
}
RegionBuildResult result = await UniTask.RunOnThreadPool(() => BuildRegionBuffers(request));
RegionBuildResult result = request.Chunks == null || request.Chunks.Length == 0
? RegionBuildResult.CreateEmpty(request.RegionCoord, request.Version, request.Session)
: await UniTask.RunOnThreadPool(() => BuildRegionBuffers(request));
if (!IsRegionBuildStillCurrent(result.RegionCoord, result.Version, result.Session))
{
buildsThisFrame++;
continue;
}
lock (regionBuildLock)
{
completedRegionBuilds.Enqueue(result);
@@ -568,6 +579,53 @@ namespace InfiniteWorld.VoxelWorld
return true;
}
private bool IsRegionBuildStillCurrent(Vector2Int regionCoord, int version, int session)
{
if (session != generationSession)
{
return false;
}
regionVersions.TryGetValue(regionCoord, out int currentVersion);
return version == currentVersion;
}
private void TryDisposeRegionIfEmpty(Vector2Int regionCoord)
{
if (RegionHasVisibleChunks(regionCoord))
{
return;
}
if (regions.TryGetValue(regionCoord, out RegionRuntime region))
{
region.Dispose();
regions.Remove(regionCoord);
}
regionVersions.Remove(regionCoord);
}
private bool RegionHasVisibleChunks(Vector2Int regionCoord)
{
Vector2Int baseChunk = new Vector2Int(regionCoord.x * renderRegionSizeInChunks, regionCoord.y * renderRegionSizeInChunks);
for (int z = 0; z < renderRegionSizeInChunks; z++)
{
for (int x = 0; x < renderRegionSizeInChunks; x++)
{
Vector2Int chunkCoord = new Vector2Int(baseChunk.x + x, baseChunk.y + z);
if (!chunks.TryGetValue(chunkCoord, out ChunkRuntime runtime) || runtime.RenderSnapshot == null || runtime.RenderSnapshot.IsEmpty)
{
continue;
}
return true;
}
}
return false;
}
private Vector2Int ChunkToRegion(Vector2Int chunkCoord)
{
return new Vector2Int(