using System.Collections.Generic; using InfiniteWorld.VoxelWorld; using InfiniteWorld.VoxelWorld.Contracts; using UnityEngine; namespace VoxelWorldScene { /// /// Combines the world generator's current stream target with scene spawn anchors into one interest feed for nav coverage. /// public sealed class SceneWorldInterestReader : IWorldInterestReader { private readonly VoxelWorldGenerator worldGenerator; private VoxelWorldSpawnAnchor[] spawnAnchors; private int lastAnchorRefreshFrame = -1; public SceneWorldInterestReader(VoxelWorldGenerator worldGenerator) { this.worldGenerator = worldGenerator; } /// /// Mirrors the generator's interest version so downstream systems can invalidate cached plans when scene interest changes. /// public int InterestVersion => worldGenerator != null ? worldGenerator.InterestVersion : 0; /// /// Appends both dynamic actor interest and static spawn-anchor interest into the supplied list. /// public void GetInterestPoints(List results) { if (results == null) { return; } worldGenerator?.GetInterestPoints(results); RefreshSpawnAnchors(); if (spawnAnchors == null) { return; } for (int i = 0; i < spawnAnchors.Length; i++) { VoxelWorldSpawnAnchor anchor = spawnAnchors[i]; if (anchor == null || !anchor.isActiveAndEnabled) { continue; } results.Add(new WorldInterestPoint(anchor.transform.position, anchor.Priority, WorldInterestKind.SpawnAnchor)); } } private void RefreshSpawnAnchors() { if (lastAnchorRefreshFrame == Time.frameCount) { return; } lastAnchorRefreshFrame = Time.frameCount; spawnAnchors = Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); } } }