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.
This commit is contained in:
Alexander Borisov
2026-04-08 20:31:16 +03:00
parent 289d5f783b
commit 2757bf3a3b
18 changed files with 917 additions and 748 deletions
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
namespace InfiniteWorld.VoxelWorld.Contracts
{
@@ -34,136 +33,4 @@ namespace InfiniteWorld.VoxelWorld.Contracts
int HintVersion { get; }
void GetHintPoints(List<WorldInterestPoint> results);
}
public readonly struct ChunkNavSourceSnapshot
{
public ChunkNavSourceSnapshot(Vector2Int coord, int version, ChunkNavBuildSourceDescriptor[] sources)
{
Coord = coord;
Version = version;
Sources = sources;
}
public Vector2Int Coord { get; }
public int Version { get; }
public ChunkNavBuildSourceDescriptor[] Sources { get; }
}
public readonly struct ChunkNavBuildSourceDescriptor
{
public ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape shape, Matrix4x4 transform, Vector3 size, Mesh mesh, int area)
{
Shape = shape;
Transform = transform;
Size = size;
Mesh = mesh;
Area = area;
}
public NavMeshBuildSourceShape Shape { get; }
public Matrix4x4 Transform { get; }
public Vector3 Size { get; }
public Mesh Mesh { get; }
public int Area { get; }
public static ChunkNavBuildSourceDescriptor CreateBox(Matrix4x4 transform, Vector3 size, int area = 0)
{
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Box, transform, size, null, area);
}
public static ChunkNavBuildSourceDescriptor CreateMesh(Matrix4x4 transform, Mesh mesh, int area = 0)
{
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Mesh, transform, Vector3.zero, mesh, area);
}
}
public readonly struct WorldInterestPoint
{
public WorldInterestPoint(Vector3 position, float priority, WorldInterestKind kind)
{
Position = position;
Priority = priority;
Kind = kind;
}
public Vector3 Position { get; }
public float Priority { get; }
public WorldInterestKind Kind { get; }
}
public enum WorldInterestKind
{
PlayerActor = 0,
ActiveNpc = 1,
SpawnAnchor = 2,
TransientNavHint = 3,
Other = 4
}
public readonly struct NavCoverageWindowSnapshot
{
public NavCoverageWindowSnapshot(int id, Bounds bounds, NavCoverageState state, int interestCount)
{
Id = id;
Bounds = bounds;
State = state;
InterestCount = interestCount;
}
public int Id { get; }
public Bounds Bounds { get; }
public NavCoverageState State { get; }
public int InterestCount { get; }
}
public enum NavCoverageState
{
Pending = 0,
Building = 1,
Ready = 2
}
public readonly struct ChunkNavGeometryReadyMessage
{
public ChunkNavGeometryReadyMessage(Vector2Int coord, int version)
{
Coord = coord;
Version = version;
}
public Vector2Int Coord { get; }
public int Version { get; }
}
public readonly struct ChunkNavGeometryRemovedMessage
{
public ChunkNavGeometryRemovedMessage(Vector2Int coord, int version)
{
Coord = coord;
Version = version;
}
public Vector2Int Coord { get; }
public int Version { get; }
}
public readonly struct WorldInterestChangedMessage
{
public WorldInterestChangedMessage(int version)
{
Version = version;
}
public int Version { get; }
}
public readonly struct NavCoverageHintChangedMessage
{
public NavCoverageHintChangedMessage(int version)
{
Version = version;
}
public int Version { get; }
}
}
@@ -0,0 +1,18 @@
namespace InfiniteWorld.VoxelWorld.Contracts
{
public enum WorldInterestKind
{
PlayerActor = 0,
ActiveNpc = 1,
SpawnAnchor = 2,
TransientNavHint = 3,
Other = 4
}
public enum NavCoverageState
{
Pending = 0,
Building = 1,
Ready = 2
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4112a97dd67e45aca6f2c0928de438bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,48 @@
using UnityEngine;
namespace InfiniteWorld.VoxelWorld.Contracts
{
public readonly struct ChunkNavGeometryReadyMessage
{
public ChunkNavGeometryReadyMessage(Vector2Int coord, int version)
{
Coord = coord;
Version = version;
}
public Vector2Int Coord { get; }
public int Version { get; }
}
public readonly struct ChunkNavGeometryRemovedMessage
{
public ChunkNavGeometryRemovedMessage(Vector2Int coord, int version)
{
Coord = coord;
Version = version;
}
public Vector2Int Coord { get; }
public int Version { get; }
}
public readonly struct WorldInterestChangedMessage
{
public WorldInterestChangedMessage(int version)
{
Version = version;
}
public int Version { get; }
}
public readonly struct NavCoverageHintChangedMessage
{
public NavCoverageHintChangedMessage(int version)
{
Version = version;
}
public int Version { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2ea3cb8fdd545019f666d378bc8eaaa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,77 @@
using UnityEngine;
using UnityEngine.AI;
namespace InfiniteWorld.VoxelWorld.Contracts
{
public readonly struct ChunkNavSourceSnapshot
{
public ChunkNavSourceSnapshot(Vector2Int coord, int version, ChunkNavBuildSourceDescriptor[] sources)
{
Coord = coord;
Version = version;
Sources = sources;
}
public Vector2Int Coord { get; }
public int Version { get; }
public ChunkNavBuildSourceDescriptor[] Sources { get; }
}
public readonly struct ChunkNavBuildSourceDescriptor
{
public ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape shape, Matrix4x4 transform, Vector3 size, Mesh mesh, int area)
{
Shape = shape;
Transform = transform;
Size = size;
Mesh = mesh;
Area = area;
}
public NavMeshBuildSourceShape Shape { get; }
public Matrix4x4 Transform { get; }
public Vector3 Size { get; }
public Mesh Mesh { get; }
public int Area { get; }
public static ChunkNavBuildSourceDescriptor CreateBox(Matrix4x4 transform, Vector3 size, int area = 0)
{
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Box, transform, size, null, area);
}
public static ChunkNavBuildSourceDescriptor CreateMesh(Matrix4x4 transform, Mesh mesh, int area = 0)
{
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Mesh, transform, Vector3.zero, mesh, area);
}
}
public readonly struct WorldInterestPoint
{
public WorldInterestPoint(Vector3 position, float priority, WorldInterestKind kind)
{
Position = position;
Priority = priority;
Kind = kind;
}
public Vector3 Position { get; }
public float Priority { get; }
public WorldInterestKind Kind { get; }
}
public readonly struct NavCoverageWindowSnapshot
{
public NavCoverageWindowSnapshot(int id, Bounds bounds, NavCoverageState state, int interestCount)
{
Id = id;
Bounds = bounds;
State = state;
InterestCount = interestCount;
}
public int Id { get; }
public Bounds Bounds { get; }
public NavCoverageState State { get; }
public int InterestCount { get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91e1b6896fdd4f7a9968cc4af4bf7550
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: