/// <summary> /// Removes old unneeded positions from the passed nearbyPositions list. /// </summary> /// <param name="nearbyPositions"></param> /// <param name="needRegenerating"></param> private void RemoveOldPositions(ref List <GridPosition> nearbyPositions, ref List <Tile> needRegenerating) { for (int i = 0; i < Cache.ActiveTiles.Count; i++) { bool found = false; foreach (GridPosition nearby in nearbyPositions) { Tile t = Cache.ActiveTiles[i]; if (t.GridPosition == nearby) //Position found in ActiveTiles { if (t.IsHeightmapLodValid()) //Correct heightmap, ignore { found = true; break; } //Invalid heightmap, mark for regeneration found = true; needRegenerating.Add(t); } } if (!found) { Cache.CacheTile(Cache.ActiveTiles[i]); Cache.ActiveTiles.RemoveAt(i); i--; } } }
/// <summary> /// Updates tiles that are surrounding the tracked GameObject /// asynchronously /// </summary> public IEnumerator UpdateTiles() { List <Vector2> nearbyPositions = GetTilePositionsFromRadius(); List <Vector2> newPositions = Cache.GetNewTilePositions(nearbyPositions); //Remove old positions for (int i = 0; i < Cache.ActiveTiles.Count; i++) { bool found = false; foreach (Vector2 nearby in nearbyPositions) { if (Cache.ActiveTiles[i].Position == nearby) //Position found, ignore { found = true; break; } } if (!found) { Cache.CacheTile(Cache.ActiveTiles[i]); Cache.ActiveTiles.RemoveAt(i); i--; } } //Add new positions foreach (Vector2 pos in newPositions) { TerrainTile cached = Cache.GetCachedTileAtPosition(pos); //Attempt to pull from cache, generate if not available if (cached != null) { Cache.AddActiveTile(cached); } else { yield return(AddTileAsync(pos)); } } }
/// <summary> /// Updates tiles that are surrounding the tracked GameObject /// asynchronously. When calling this method using /// <see cref="MonoBehaviour.StartCoroutine(System.Collections.IEnumerator)"/>, /// tiles are generated once per frame /// </summary> public IEnumerator UpdateTiles() { List <GridPosition> nearbyPositions = GetTilePositionsFromRadius(); List <GridPosition> newPositions = Cache.GetNewTilePositions(nearbyPositions); List <Tile> needRegenerating = new List <Tile>(); //Remove old positions for (int i = 0; i < Cache.ActiveTiles.Count; i++) { bool found = false; foreach (GridPosition nearby in nearbyPositions) { Tile t = Cache.ActiveTiles[i]; if (t.GridPosition == nearby) //Position found in ActiveTiles { if (t.IsHeightmapLodValid()) //Correct heightmap, ignore { found = true; break; } //Invalid heightmap, mark for regeneration found = true; needRegenerating.Add(t); } } if (!found) { Cache.CacheTile(Cache.ActiveTiles[i]); Cache.ActiveTiles.RemoveAt(i); i--; } } //Add new positions _queuedTiles = newPositions.Count + needRegenerating.Count; foreach (GridPosition pos in newPositions) { Tile cached = Cache.GetCachedTileAtPosition(pos); //Attempt to pull from cache, generate if not available if (cached != null) { if (cached.IsHeightmapLodValid()) //Cached tile is valid, use it { AddTile(cached); _queuedTiles--; continue; } //Cached tile has too low lod, mark for regeneration Debug.Log("Cached tile " + cached + " has heightmap res=" + cached.MeshManager.MeshResolution + ". requested res=" + cached.LodLevel.MeshResolution + ". Regenerating."); //Cache.RemoveCachedTile(cached); needRegenerating.Add(cached); Cache.AddActiveTile(cached); continue; } //Generate one tile per frame if (Application.isPlaying) { yield return(null); } _isGeneratingTile = true; AddTileAt(pos, tile => { _queuedTiles--; _isGeneratingTile = false; if (_queuedTiles == 0) { _queueCompletedAction(newPositions.ToArray()); } }); } //Regenerate tiles with outdated positions for (int i = 0; i < needRegenerating.Count; i++) { Tile t = needRegenerating[i]; Debug.Log("Active tile " + t + " has heightmap res=" + t.MeshManager.MeshResolution + ". requested res=" + t.LodLevel.MeshResolution + ". Regenerating."); //Generate one tile per frame if (Application.isPlaying) { yield return(null); } _isGeneratingTile = true; AddTileAt(t.GridPosition, tile => { _queuedTiles--; _isGeneratingTile = false; //Remove low res tile Cache.RemoveActiveTile(t); Cache.RemoveCachedTile(t); if (_queuedTiles == 0) { _queueCompletedAction(newPositions.ToArray()); } }); } //If tiles were updated synchronously, notify queue completion if (newPositions.Count > 0 && _queuedTiles == 0) { _queueCompletedAction(newPositions.ToArray()); } }