Files
TheDeclineOfWarriors/Assets/Features/VoxelWorldNavMesh/Runtime/NavBuildSourceCollector.cs
T
Alexander Borisov 2757bf3a3b reorganize navmesh contracts and services
Split VoxelWorld nav contracts into focused files and extract clustered coverage helpers so the navmesh service stays a coordinator instead of a catch-all runtime file.
2026-04-08 20:31:16 +03:00

85 lines
3.3 KiB
C#

using System.Collections.Generic;
using InfiniteWorld.VoxelWorld.Contracts;
using UnityEngine;
using UnityEngine.AI;
namespace InfiniteWorld.VoxelWorld.NavMesh
{
internal static class NavBuildSourceCollector
{
public static bool CollectBuildSources(
IChunkNavSourceReader chunkNavSourceReader,
Bounds coverageBounds,
List<Vector2Int> loadedChunkCoords,
List<NavMeshBuildSource> results)
{
loadedChunkCoords.Clear();
chunkNavSourceReader.GetLoadedChunkCoords(loadedChunkCoords);
bool hasSources = false;
for (int i = 0; i < loadedChunkCoords.Count; i++)
{
Vector2Int chunkCoord = loadedChunkCoords[i];
if (!NavMeshBoundsUtility.IntersectsXZ(GetChunkWorldBounds(chunkNavSourceReader, chunkCoord), coverageBounds))
{
continue;
}
if (!chunkNavSourceReader.TryGetChunkNavSourceSnapshot(chunkCoord, out ChunkNavSourceSnapshot snapshot) || snapshot.Sources == null || snapshot.Sources.Length == 0)
{
continue;
}
hasSources = true;
AppendBuildSources(snapshot.Sources, results);
}
return hasSources;
}
public static Bounds GetChunkWorldBounds(IChunkNavSourceReader chunkNavSourceReader, Vector2Int chunkCoord)
{
float chunkSize = Mathf.Max(1f, chunkNavSourceReader.ChunkWorldSize);
Vector3 min = new Vector3(chunkCoord.x * chunkSize, -500f, chunkCoord.y * chunkSize);
Vector3 size = new Vector3(chunkSize, 1000f, chunkSize);
return new Bounds(min + new Vector3(chunkSize * 0.5f, 0f, chunkSize * 0.5f), size);
}
public static Bounds ExpandCoverageBounds(IChunkNavSourceReader chunkNavSourceReader, Bounds bounds, int chunkMargin)
{
return ExpandChunkBounds(chunkNavSourceReader, bounds, chunkMargin);
}
public static Bounds ExpandChunkBounds(IChunkNavSourceReader chunkNavSourceReader, Bounds bounds, int chunkMargin)
{
float chunkSize = Mathf.Max(1f, chunkNavSourceReader.ChunkWorldSize);
float horizontalPadding = chunkMargin * chunkSize;
bounds.Expand(new Vector3(horizontalPadding * 2f, 0f, horizontalPadding * 2f));
return bounds;
}
private static void AppendBuildSources(ChunkNavBuildSourceDescriptor[] descriptors, List<NavMeshBuildSource> results)
{
for (int i = 0; i < descriptors.Length; i++)
{
ChunkNavBuildSourceDescriptor descriptor = descriptors[i];
if (descriptor.Shape == NavMeshBuildSourceShape.Mesh && descriptor.Mesh == null)
{
continue;
}
NavMeshBuildSource source = new NavMeshBuildSource
{
area = descriptor.Area,
shape = descriptor.Shape,
transform = descriptor.Transform,
size = descriptor.Size,
sourceObject = descriptor.Shape == NavMeshBuildSourceShape.Mesh ? descriptor.Mesh : null
};
results.Add(source);
}
}
}
}