add documentation
This commit is contained in:
@@ -3,34 +3,88 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace InfiniteWorld.VoxelWorld.Contracts
|
namespace InfiniteWorld.VoxelWorld.Contracts
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides chunk-level nav build inputs without exposing the internal runtime representation of the voxel world.
|
||||||
|
/// </summary>
|
||||||
public interface IChunkNavSourceReader
|
public interface IChunkNavSourceReader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the world-space edge length of one chunk so nav coverage and source collection can reason in chunk units.
|
||||||
|
/// </summary>
|
||||||
float ChunkWorldSize { get; }
|
float ChunkWorldSize { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the coordinates of chunks that currently have usable nav geometry into the provided list.
|
||||||
|
/// </summary>
|
||||||
void GetLoadedChunkCoords(List<Vector2Int> results);
|
void GetLoadedChunkCoords(List<Vector2Int> results);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the current nav source snapshot for a loaded chunk so sidecar systems can rebuild coverage from stable descriptors.
|
||||||
|
/// </summary>
|
||||||
bool TryGetChunkNavSourceSnapshot(Vector2Int coord, out ChunkNavSourceSnapshot snapshot);
|
bool TryGetChunkNavSourceSnapshot(Vector2Int coord, out ChunkNavSourceSnapshot snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exposes the current gameplay-relevant interest points that should influence world streaming or nav coverage planning.
|
||||||
|
/// </summary>
|
||||||
public interface IWorldInterestReader
|
public interface IWorldInterestReader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Increments when the logical set of interest points changes and downstream systems should invalidate cached plans.
|
||||||
|
/// </summary>
|
||||||
int InterestVersion { get; }
|
int InterestVersion { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends the currently active interest points into the provided list.
|
||||||
|
/// </summary>
|
||||||
void GetInterestPoints(List<WorldInterestPoint> results);
|
void GetInterestPoints(List<WorldInterestPoint> results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exposes the currently built nav coverage so gameplay systems can query whether a world-space area is ready for pathing.
|
||||||
|
/// </summary>
|
||||||
public interface INavCoverageReader
|
public interface INavCoverageReader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the supplied world position lies inside ready nav coverage, not merely inside generated terrain.
|
||||||
|
/// </summary>
|
||||||
bool IsPositionCovered(Vector3 worldPosition);
|
bool IsPositionCovered(Vector3 worldPosition);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the currently active coverage windows so diagnostics and higher-level systems can inspect the coverage topology.
|
||||||
|
/// </summary>
|
||||||
void GetCoverageWindows(List<NavCoverageWindowSnapshot> results);
|
void GetCoverageWindows(List<NavCoverageWindowSnapshot> results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lets callers inject short-lived route hints that bias nav coverage planning toward an upcoming movement corridor.
|
||||||
|
/// </summary>
|
||||||
public interface INavCoverageHintRegistry
|
public interface INavCoverageHintRegistry
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers or refreshes a temporary linear hint for the given owner so coverage can prewarm along a route before pathing starts.
|
||||||
|
/// </summary>
|
||||||
void SetLinearHint(int ownerId, Vector3 from, Vector3 to, float priority, float ttlSeconds);
|
void SetLinearHint(int ownerId, Vector3 from, Vector3 to, float priority, float ttlSeconds);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the temporary hint owned by the caller when the route is no longer relevant.
|
||||||
|
/// </summary>
|
||||||
void ClearHint(int ownerId);
|
void ClearHint(int ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exposes the current set of transient nav coverage hints as read-only interest points for the nav coverage scheduler.
|
||||||
|
/// </summary>
|
||||||
public interface INavCoverageHintReader
|
public interface INavCoverageHintReader
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Increments whenever the effective hint set changes so dependent planners can invalidate cached coverage windows.
|
||||||
|
/// </summary>
|
||||||
int HintVersion { get; }
|
int HintVersion { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends the currently active transient hint points into the provided list.
|
||||||
|
/// </summary>
|
||||||
void GetHintPoints(List<WorldInterestPoint> results);
|
void GetHintPoints(List<WorldInterestPoint> results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,38 @@
|
|||||||
namespace InfiniteWorld.VoxelWorld.Contracts
|
namespace InfiniteWorld.VoxelWorld.Contracts
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies why a point contributes to nav coverage so planners and diagnostics can treat different sources appropriately.
|
||||||
|
/// </summary>
|
||||||
public enum WorldInterestKind
|
public enum WorldInterestKind
|
||||||
{
|
{
|
||||||
|
/// <summary>Coverage seeded by the current player-controlled actor.</summary>
|
||||||
PlayerActor = 0,
|
PlayerActor = 0,
|
||||||
|
|
||||||
|
/// <summary>Coverage seeded by an active NPC that still requires authoritative pathing.</summary>
|
||||||
ActiveNpc = 1,
|
ActiveNpc = 1,
|
||||||
|
|
||||||
|
/// <summary>Coverage seeded by a spawn location that should be warm before actors start moving.</summary>
|
||||||
SpawnAnchor = 2,
|
SpawnAnchor = 2,
|
||||||
|
|
||||||
|
/// <summary>Coverage seeded by a short-lived route hint that biases planning ahead of movement.</summary>
|
||||||
TransientNavHint = 3,
|
TransientNavHint = 3,
|
||||||
|
|
||||||
|
/// <summary>Fallback category for future interest sources that do not fit a more specific kind.</summary>
|
||||||
Other = 4
|
Other = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes where a coverage window currently sits in the nav build lifecycle.
|
||||||
|
/// </summary>
|
||||||
public enum NavCoverageState
|
public enum NavCoverageState
|
||||||
{
|
{
|
||||||
|
/// <summary>The window exists conceptually but still needs a fresh build.</summary>
|
||||||
Pending = 0,
|
Pending = 0,
|
||||||
|
|
||||||
|
/// <summary>The window is currently rebuilding its runtime NavMesh data.</summary>
|
||||||
Building = 1,
|
Building = 1,
|
||||||
|
|
||||||
|
/// <summary>The window has ready NavMesh data that can answer pathing queries.</summary>
|
||||||
Ready = 2
|
Ready = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace InfiniteWorld.VoxelWorld.Contracts
|
namespace InfiniteWorld.VoxelWorld.Contracts
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Signals that a chunk now has valid nav geometry and dependent coverage windows should invalidate cached builds.
|
||||||
|
/// </summary>
|
||||||
public readonly struct ChunkNavGeometryReadyMessage
|
public readonly struct ChunkNavGeometryReadyMessage
|
||||||
{
|
{
|
||||||
public ChunkNavGeometryReadyMessage(Vector2Int coord, int version)
|
public ChunkNavGeometryReadyMessage(Vector2Int coord, int version)
|
||||||
@@ -10,10 +13,20 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Version = version;
|
Version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chunk coordinate whose nav geometry became available.
|
||||||
|
/// </summary>
|
||||||
public Vector2Int Coord { get; }
|
public Vector2Int Coord { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Version of the chunk runtime state associated with this notification.
|
||||||
|
/// </summary>
|
||||||
public int Version { get; }
|
public int Version { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signals that a chunk's nav geometry is being removed so dependent coverage windows can drop stale build data.
|
||||||
|
/// </summary>
|
||||||
public readonly struct ChunkNavGeometryRemovedMessage
|
public readonly struct ChunkNavGeometryRemovedMessage
|
||||||
{
|
{
|
||||||
public ChunkNavGeometryRemovedMessage(Vector2Int coord, int version)
|
public ChunkNavGeometryRemovedMessage(Vector2Int coord, int version)
|
||||||
@@ -22,10 +35,20 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Version = version;
|
Version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chunk coordinate whose nav geometry is no longer available.
|
||||||
|
/// </summary>
|
||||||
public Vector2Int Coord { get; }
|
public Vector2Int Coord { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last known version of the chunk state before removal.
|
||||||
|
/// </summary>
|
||||||
public int Version { get; }
|
public int Version { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalidates consumers that cache the current world interest set.
|
||||||
|
/// </summary>
|
||||||
public readonly struct WorldInterestChangedMessage
|
public readonly struct WorldInterestChangedMessage
|
||||||
{
|
{
|
||||||
public WorldInterestChangedMessage(int version)
|
public WorldInterestChangedMessage(int version)
|
||||||
@@ -33,9 +56,15 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Version = version;
|
Version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Monotonic version of the world interest state after the change.
|
||||||
|
/// </summary>
|
||||||
public int Version { get; }
|
public int Version { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalidates consumers that cache transient nav coverage hints.
|
||||||
|
/// </summary>
|
||||||
public readonly struct NavCoverageHintChangedMessage
|
public readonly struct NavCoverageHintChangedMessage
|
||||||
{
|
{
|
||||||
public NavCoverageHintChangedMessage(int version)
|
public NavCoverageHintChangedMessage(int version)
|
||||||
@@ -43,6 +72,9 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Version = version;
|
Version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Monotonic version of the active nav hint state after the change.
|
||||||
|
/// </summary>
|
||||||
public int Version { get; }
|
public int Version { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ using UnityEngine.AI;
|
|||||||
|
|
||||||
namespace InfiniteWorld.VoxelWorld.Contracts
|
namespace InfiniteWorld.VoxelWorld.Contracts
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Captures the nav-relevant state of one chunk at a specific version so sidecar systems can rebuild from immutable inputs.
|
||||||
|
/// </summary>
|
||||||
public readonly struct ChunkNavSourceSnapshot
|
public readonly struct ChunkNavSourceSnapshot
|
||||||
{
|
{
|
||||||
public ChunkNavSourceSnapshot(Vector2Int coord, int version, ChunkNavBuildSourceDescriptor[] sources)
|
public ChunkNavSourceSnapshot(Vector2Int coord, int version, ChunkNavBuildSourceDescriptor[] sources)
|
||||||
@@ -12,11 +15,25 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Sources = sources;
|
Sources = sources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chunk coordinate this snapshot was produced for.
|
||||||
|
/// </summary>
|
||||||
public Vector2Int Coord { get; }
|
public Vector2Int Coord { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Version of the chunk runtime state used to generate this snapshot.
|
||||||
|
/// </summary>
|
||||||
public int Version { get; }
|
public int Version { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stable nav build descriptors derived from the chunk's current geometry.
|
||||||
|
/// </summary>
|
||||||
public ChunkNavBuildSourceDescriptor[] Sources { get; }
|
public ChunkNavBuildSourceDescriptor[] Sources { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Describes one build source in a format that can be consumed without direct references to world internals or scene scans.
|
||||||
|
/// </summary>
|
||||||
public readonly struct ChunkNavBuildSourceDescriptor
|
public readonly struct ChunkNavBuildSourceDescriptor
|
||||||
{
|
{
|
||||||
public ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape shape, Matrix4x4 transform, Vector3 size, Mesh mesh, int area)
|
public ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape shape, Matrix4x4 transform, Vector3 size, Mesh mesh, int area)
|
||||||
@@ -28,23 +45,51 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Area = area;
|
Area = area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unity NavMesh source shape represented by this descriptor.
|
||||||
|
/// </summary>
|
||||||
public NavMeshBuildSourceShape Shape { get; }
|
public NavMeshBuildSourceShape Shape { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// World transform used when the descriptor is converted into a runtime build source.
|
||||||
|
/// </summary>
|
||||||
public Matrix4x4 Transform { get; }
|
public Matrix4x4 Transform { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Source size for primitive shapes such as box-based ground coverage.
|
||||||
|
/// </summary>
|
||||||
public Vector3 Size { get; }
|
public Vector3 Size { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Source mesh for mesh-based obstacles or walkable surfaces when applicable.
|
||||||
|
/// </summary>
|
||||||
public Mesh Mesh { get; }
|
public Mesh Mesh { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Nav area assigned to the resulting build source.
|
||||||
|
/// </summary>
|
||||||
public int Area { get; }
|
public int Area { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a compact descriptor for box-based chunk geometry such as ground slabs.
|
||||||
|
/// </summary>
|
||||||
public static ChunkNavBuildSourceDescriptor CreateBox(Matrix4x4 transform, Vector3 size, int area = 0)
|
public static ChunkNavBuildSourceDescriptor CreateBox(Matrix4x4 transform, Vector3 size, int area = 0)
|
||||||
{
|
{
|
||||||
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Box, transform, size, null, area);
|
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Box, transform, size, null, area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a compact descriptor for mesh-based chunk geometry such as carved terrain or obstacles.
|
||||||
|
/// </summary>
|
||||||
public static ChunkNavBuildSourceDescriptor CreateMesh(Matrix4x4 transform, Mesh mesh, int area = 0)
|
public static ChunkNavBuildSourceDescriptor CreateMesh(Matrix4x4 transform, Mesh mesh, int area = 0)
|
||||||
{
|
{
|
||||||
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Mesh, transform, Vector3.zero, mesh, area);
|
return new ChunkNavBuildSourceDescriptor(NavMeshBuildSourceShape.Mesh, transform, Vector3.zero, mesh, area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents one gameplay-driven point that should influence nav coverage planning and clustering.
|
||||||
|
/// </summary>
|
||||||
public readonly struct WorldInterestPoint
|
public readonly struct WorldInterestPoint
|
||||||
{
|
{
|
||||||
public WorldInterestPoint(Vector3 position, float priority, WorldInterestKind kind)
|
public WorldInterestPoint(Vector3 position, float priority, WorldInterestKind kind)
|
||||||
@@ -54,11 +99,25 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
Kind = kind;
|
Kind = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// World position the planner should consider when shaping coverage.
|
||||||
|
/// </summary>
|
||||||
public Vector3 Position { get; }
|
public Vector3 Position { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative weight used to prioritize coverage near more important interest points.
|
||||||
|
/// </summary>
|
||||||
public float Priority { get; }
|
public float Priority { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Category of interest so diagnostics can distinguish players, spawn anchors, hints and future AI sources.
|
||||||
|
/// </summary>
|
||||||
public WorldInterestKind Kind { get; }
|
public WorldInterestKind Kind { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lightweight read-model snapshot describing one currently managed nav coverage window.
|
||||||
|
/// </summary>
|
||||||
public readonly struct NavCoverageWindowSnapshot
|
public readonly struct NavCoverageWindowSnapshot
|
||||||
{
|
{
|
||||||
public NavCoverageWindowSnapshot(int id, Bounds bounds, NavCoverageState state, int interestCount)
|
public NavCoverageWindowSnapshot(int id, Bounds bounds, NavCoverageState state, int interestCount)
|
||||||
@@ -69,9 +128,24 @@ namespace InfiniteWorld.VoxelWorld.Contracts
|
|||||||
InterestCount = interestCount;
|
InterestCount = interestCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stable runtime identifier of the coverage window.
|
||||||
|
/// </summary>
|
||||||
public int Id { get; }
|
public int Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// World-space bounds the window currently covers for pathing readiness.
|
||||||
|
/// </summary>
|
||||||
public Bounds Bounds { get; }
|
public Bounds Bounds { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current lifecycle state of the window in the build scheduler.
|
||||||
|
/// </summary>
|
||||||
public NavCoverageState State { get; }
|
public NavCoverageState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of interest points currently collapsed into this window.
|
||||||
|
/// </summary>
|
||||||
public int InterestCount { get; }
|
public int InterestCount { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ using VContainer.Unity;
|
|||||||
|
|
||||||
namespace InfiniteWorld.VoxelWorld.NavMesh
|
namespace InfiniteWorld.VoxelWorld.NavMesh
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stores short-lived route hints and expands them into interest points so nav coverage can prewarm ahead of movement.
|
||||||
|
/// </summary>
|
||||||
public sealed class NavCoverageHintService : ITickable, INavCoverageHintRegistry, INavCoverageHintReader
|
public sealed class NavCoverageHintService : ITickable, INavCoverageHintRegistry, INavCoverageHintReader
|
||||||
{
|
{
|
||||||
private readonly IChunkNavSourceReader chunkNavSourceReader;
|
private readonly IChunkNavSourceReader chunkNavSourceReader;
|
||||||
@@ -27,8 +30,14 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
this.hintChangedPublisher = hintChangedPublisher;
|
this.hintChangedPublisher = hintChangedPublisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increments whenever the effective set of active hints changes and cached coverage planning should be invalidated.
|
||||||
|
/// </summary>
|
||||||
public int HintVersion => hintVersion;
|
public int HintVersion => hintVersion;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Expires hints whose time-to-live has elapsed so stale route bias does not keep shaping coverage forever.
|
||||||
|
/// </summary>
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
if (hints.Count == 0)
|
if (hints.Count == 0)
|
||||||
@@ -61,6 +70,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
NotifyHintsChanged();
|
NotifyHintsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers or refreshes a temporary linear corridor for one owner so coverage can be biased along an upcoming route.
|
||||||
|
/// </summary>
|
||||||
public void SetLinearHint(int ownerId, Vector3 from, Vector3 to, float priority, float ttlSeconds)
|
public void SetLinearHint(int ownerId, Vector3 from, Vector3 to, float priority, float ttlSeconds)
|
||||||
{
|
{
|
||||||
if (ownerId == 0)
|
if (ownerId == 0)
|
||||||
@@ -74,6 +86,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
NotifyHintsChanged();
|
NotifyHintsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a previously registered route hint once the owner no longer needs prewarmed coverage.
|
||||||
|
/// </summary>
|
||||||
public void ClearHint(int ownerId)
|
public void ClearHint(int ownerId)
|
||||||
{
|
{
|
||||||
if (!hints.Remove(ownerId))
|
if (!hints.Remove(ownerId))
|
||||||
@@ -84,6 +99,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
NotifyHintsChanged();
|
NotifyHintsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends the currently active hint points so the main coverage scheduler can treat them like supplemental interest.
|
||||||
|
/// </summary>
|
||||||
public void GetHintPoints(List<WorldInterestPoint> results)
|
public void GetHintPoints(List<WorldInterestPoint> results)
|
||||||
{
|
{
|
||||||
if (results == null)
|
if (results == null)
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ using UnityEngine;
|
|||||||
namespace InfiniteWorld.VoxelWorld.NavMesh
|
namespace InfiniteWorld.VoxelWorld.NavMesh
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
/// <summary>
|
||||||
|
/// Inspector-friendly tuning parameters that bound how clustered nav coverage is shaped and rebuilt at runtime.
|
||||||
|
/// </summary>
|
||||||
public sealed class VoxelWorldNavMeshConfig
|
public sealed class VoxelWorldNavMeshConfig
|
||||||
{
|
{
|
||||||
[Min(0)] public int agentTypeId;
|
[Min(0)] public int agentTypeId;
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ using UnityNavMeshBuilder = UnityEngine.AI.NavMeshBuilder;
|
|||||||
|
|
||||||
namespace InfiniteWorld.VoxelWorld.NavMesh
|
namespace InfiniteWorld.VoxelWorld.NavMesh
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Coordinates clustered runtime NavMesh coverage over the voxel world by rebuilding a bounded set of windows around active interest.
|
||||||
|
/// </summary>
|
||||||
public sealed class VoxelWorldNavMeshService : IStartable, ITickable, IDisposable, INavCoverageReader
|
public sealed class VoxelWorldNavMeshService : IStartable, ITickable, IDisposable, INavCoverageReader
|
||||||
{
|
{
|
||||||
private readonly IChunkNavSourceReader chunkNavSourceReader;
|
private readonly IChunkNavSourceReader chunkNavSourceReader;
|
||||||
@@ -54,6 +57,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
this.config = config ?? new VoxelWorldNavMeshConfig();
|
this.config = config ?? new VoxelWorldNavMeshConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subscribes to world invalidation and primes the initial set of coverage windows for the current interest snapshot.
|
||||||
|
/// </summary>
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
subscriptions.Add(chunkReadySubscriber.Subscribe(OnChunkNavGeometryReady));
|
subscriptions.Add(chunkReadySubscriber.Subscribe(OnChunkNavGeometryReady));
|
||||||
@@ -66,6 +72,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
MarkAllCoverageWindowsDirty();
|
MarkAllCoverageWindowsDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advances the clustered coverage scheduler, refreshing interest and starting bounded asynchronous builds when needed.
|
||||||
|
/// </summary>
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
RefreshInterestPoints();
|
RefreshInterestPoints();
|
||||||
@@ -92,6 +101,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the supplied world position is inside a ready coverage window and can be treated as nav-ready.
|
||||||
|
/// </summary>
|
||||||
public bool IsPositionCovered(Vector3 worldPosition)
|
public bool IsPositionCovered(Vector3 worldPosition)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, NavCoverageWindowRuntime> pair in coverageWindows)
|
foreach (KeyValuePair<int, NavCoverageWindowRuntime> pair in coverageWindows)
|
||||||
@@ -106,6 +118,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the current runtime coverage windows for diagnostics, readiness checks and higher-level planning.
|
||||||
|
/// </summary>
|
||||||
public void GetCoverageWindows(List<NavCoverageWindowSnapshot> results)
|
public void GetCoverageWindows(List<NavCoverageWindowSnapshot> results)
|
||||||
{
|
{
|
||||||
if (results == null)
|
if (results == null)
|
||||||
@@ -120,6 +135,9 @@ namespace InfiniteWorld.VoxelWorld.NavMesh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases subscriptions and runtime NavMesh data owned by the service.
|
||||||
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < subscriptions.Count; i++)
|
for (int i = 0; i < subscriptions.Count; i++)
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace VoxelWorldScene
|
namespace VoxelWorldScene
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Combines the world generator's current stream target with scene spawn anchors into one interest feed for nav coverage.
|
||||||
|
/// </summary>
|
||||||
public sealed class SceneWorldInterestReader : IWorldInterestReader
|
public sealed class SceneWorldInterestReader : IWorldInterestReader
|
||||||
{
|
{
|
||||||
private readonly VoxelWorldGenerator worldGenerator;
|
private readonly VoxelWorldGenerator worldGenerator;
|
||||||
@@ -16,8 +19,14 @@ namespace VoxelWorldScene
|
|||||||
this.worldGenerator = worldGenerator;
|
this.worldGenerator = worldGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mirrors the generator's interest version so downstream systems can invalidate cached plans when scene interest changes.
|
||||||
|
/// </summary>
|
||||||
public int InterestVersion => worldGenerator != null ? worldGenerator.InterestVersion : 0;
|
public int InterestVersion => worldGenerator != null ? worldGenerator.InterestVersion : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends both dynamic actor interest and static spawn-anchor interest into the supplied list.
|
||||||
|
/// </summary>
|
||||||
public void GetInterestPoints(List<WorldInterestPoint> results)
|
public void GetInterestPoints(List<WorldInterestPoint> results)
|
||||||
{
|
{
|
||||||
if (results == null)
|
if (results == null)
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ namespace VoxelWorldScene
|
|||||||
{
|
{
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
[RequireComponent(typeof(VoxelWorldGenerator))]
|
[RequireComponent(typeof(VoxelWorldGenerator))]
|
||||||
|
/// <summary>
|
||||||
|
/// Scene-level composition root that wires the voxel world, nav coverage services and interest readers into one runtime module.
|
||||||
|
/// </summary>
|
||||||
public sealed class VoxelWorldNavMeshLifetimeScope : LifetimeScope
|
public sealed class VoxelWorldNavMeshLifetimeScope : LifetimeScope
|
||||||
{
|
{
|
||||||
[SerializeField] private bool enableRuntimeNavMesh = true;
|
[SerializeField] private bool enableRuntimeNavMesh = true;
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ namespace VoxelWorldScene
|
|||||||
{
|
{
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
[RequireComponent(typeof(VoxelWorldGenerator))]
|
[RequireComponent(typeof(VoxelWorldGenerator))]
|
||||||
|
/// <summary>
|
||||||
|
/// Keeps the voxel world streaming target aligned with the local player when available, or a spawn anchor as a safe fallback.
|
||||||
|
/// </summary>
|
||||||
public sealed class VoxelWorldPlayerStreamTargetBinding : MonoBehaviour
|
public sealed class VoxelWorldPlayerStreamTargetBinding : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private VoxelWorldGenerator worldGenerator;
|
[SerializeField] private VoxelWorldGenerator worldGenerator;
|
||||||
|
|||||||
@@ -3,10 +3,16 @@ using UnityEngine;
|
|||||||
namespace VoxelWorldScene
|
namespace VoxelWorldScene
|
||||||
{
|
{
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
|
/// <summary>
|
||||||
|
/// Marks a scene transform that should contribute interest before players move so spawn areas can be prewarmed for nav coverage.
|
||||||
|
/// </summary>
|
||||||
public sealed class VoxelWorldSpawnAnchor : MonoBehaviour
|
public sealed class VoxelWorldSpawnAnchor : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField, Min(0.01f)] private float priority = 2f;
|
[SerializeField, Min(0.01f)] private float priority = 2f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relative importance of this anchor when coverage planning competes between multiple spawn-related interests.
|
||||||
|
/// </summary>
|
||||||
public float Priority => priority;
|
public float Priority => priority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user