Esempio n. 1
0
 /// <summary>
 /// Responds to chunk collider callbacks. Updates the navmesh based on the new collider data.
 /// </summary>
 /// <param name="chunk"></param>
 private void OnTerrainChunkColliderChanged(TerrainChunk chunk, bool hasSetCollider)
 {
     if (hasSetCollider)
     {
         if (IsBuildingNavmesh)
         {
             StopCoroutine(BuildNavMeshAsync());
         }
         StartCoroutine(BuildNavMeshAsync());
     }
 }
Esempio n. 2
0
 /// <summary>
 /// Responds to chunk visibility callbacks. Adds the chunk to a list of visible terrainChunks.
 /// </summary>
 /// <param name="chunk"></param>
 /// <param name="isVisible"></param>
 private void OnTerrainChunkVisibilityChanged(TerrainChunk chunk, bool isVisible)
 {
     if (isVisible)
     {
         visibleTerrainChunks.Add(chunk);
     }
     else
     {
         visibleTerrainChunks.Remove(chunk);
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Update all visible chunks, tries to find new chunks aswell.
        /// </summary>
        private void UpdateVisibleChunks()
        {
            // Update the current visible chunks
            HashSet <Vector2> alreadyUpdatedChunkCoords = new HashSet <Vector2>();

            for (int i = visibleTerrainChunks.Count - 1; i >= 0; i--)
            {
                alreadyUpdatedChunkCoords.Add(visibleTerrainChunks[i].Coord);
                visibleTerrainChunks[i].UpdateTerrainChunk();
            }

            for (int yOffset = -1; yOffset <= 1; yOffset++)
            {
                for (int xOffset = -1; xOffset <= 1; xOffset++)
                {
                    // Find new chunks based on secondary viewer positions
                    foreach (var secondaryViewer in secondaryViewers.Values)
                    {
                        if (secondaryViewer.Transform == null)
                        {
                            Debug.LogWarning("Viewer has no transform");
                            continue;
                        }

                        int secondaryViewerChunkCoordX = Mathf.RoundToInt(secondaryViewer.Position.x / meshWorldSize);
                        int secondaryViewerChunkCoordY = Mathf.RoundToInt(secondaryViewer.Position.y / meshWorldSize);

                        Vector2 viewedChunkCoord = new Vector2(secondaryViewerChunkCoordX + xOffset, secondaryViewerChunkCoordY + yOffset);
                        if (!alreadyUpdatedChunkCoords.Contains(viewedChunkCoord))
                        {
                            if (terrainChunkDictionary.ContainsKey(viewedChunkCoord))
                            {
                                TerrainChunk terrainChunk = terrainChunkDictionary[viewedChunkCoord];
                                terrainChunk.Viewer = secondaryViewer;
                            }
                            else
                            {
                                TerrainChunk newChunk = new TerrainChunk(viewedChunkCoord, HeightMapSettings, BiomeMapSettings, ResourceMapSettings, MeshSettings, detailLevels, colliderLODIndex, transform, secondaryViewer, TerrainMeshMaterial);
                                terrainChunkDictionary.Add(viewedChunkCoord, newChunk);
                                newChunk.OnVisibilityChanged += OnTerrainChunkVisibilityChanged;
                                newChunk.OnColliderChanged   += OnTerrainChunkColliderChanged;
                                newChunk.Load();
                            }
                        }
                    }
                }
            }

            // Find new chunks based on primary viewer position
            int primaryViewerChunkCoordX = Mathf.RoundToInt(primaryViewer.Position.x / meshWorldSize);
            int primaryViewerChunkCoordY = Mathf.RoundToInt(primaryViewer.Position.y / meshWorldSize);

            for (int yOffset = -chunksVisibleInViewDistance; yOffset <= chunksVisibleInViewDistance; yOffset++)
            {
                for (int xOffset = -chunksVisibleInViewDistance; xOffset <= chunksVisibleInViewDistance; xOffset++)
                {
                    Vector2 viewedChunkCoord = new Vector2(primaryViewerChunkCoordX + xOffset, primaryViewerChunkCoordY + yOffset);
                    if (!alreadyUpdatedChunkCoords.Contains(viewedChunkCoord))
                    {
                        if (terrainChunkDictionary.ContainsKey(viewedChunkCoord))
                        {
                            TerrainChunk terrainChunk = terrainChunkDictionary[viewedChunkCoord];
                            terrainChunk.Viewer = primaryViewer;

                            terrainChunk.UpdateTerrainChunk();
                        }
                        else
                        {
                            TerrainChunk newChunk = new TerrainChunk(viewedChunkCoord, HeightMapSettings, BiomeMapSettings, ResourceMapSettings, MeshSettings, detailLevels, colliderLODIndex, transform, primaryViewer, TerrainMeshMaterial);
                            terrainChunkDictionary.Add(viewedChunkCoord, newChunk);
                            newChunk.OnVisibilityChanged += OnTerrainChunkVisibilityChanged;
                            newChunk.OnColliderChanged   += OnTerrainChunkColliderChanged;
                            newChunk.Load();
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        public static ObjectPoint[] CreateObjectPoints(int uniformSize, MeshSettings meshSettings, ResourceMapSettings resourceMapSettings, BiomeMap biomeMap, HeightMap heightMap, TerrainChunk terrainChunk)
        {
            string fileName = $"chunkInfo{terrainChunk.Coord.x}{terrainChunk.Coord.y}.dat";

            // Try to load a save file
            if (File.Exists(SaveDataManager.WorldDataPath + fileName))
            {
                return(ObjectMapLoader.LoadObjectMap(terrainChunk, SaveDataManager.WorldDataPath).ObjectPoints);
            }
            else
            {
                //ResourceMap resourceMap = ResourceMapGenerator.GenerateResourceMap(uniformSize, resourceMapSettings, terrainChunk.SampleCenter);

                ResourceMap resourceMap = ResourceMapGenerator.GenerateResourceMap(uniformSize, resourceMapSettings, terrainChunk.SampleCenter, biomeMap, heightMap);

                List <ObjectPoint> tempObjectPoints = new List <ObjectPoint>();

                // Resource points to object points
                foreach (var resourcePoint in resourceMap.resourcePoints)
                {
                    int x = resourcePoint.x;
                    int z = resourcePoint.z;

                    HeightMapLayer layer = heightMap.GetLayer(x + 1, z + 1);

                    // Don't spawn objects on water.
                    if (layer.IsWater)
                    {
                        continue;
                    }

                    float   height   = heightMap.Values[x + 1, z + 1];
                    Vector3 position = new Vector3(terrainChunk.Bounds.center.x, 0f, terrainChunk.Bounds.center.y) + new Vector3((x - (uniformSize - 1) / 2f) * meshSettings.MeshScale, height, (z - (uniformSize - 1) / 2f) * -meshSettings.MeshScale);

                    // Create a seeded System.Random for the rotation based on the position
                    float         a    = position.x + position.y;
                    float         b    = position.z + position.y;
                    System.Random rand = new System.Random((int)(0.5 * (a + b) * (a + b + 1) + b));

                    Quaternion rotation = Quaternion.Euler(new Vector3(0f, rand.Next(0, 360), 0f));

                    int chunkPartSize = uniformSize / meshSettings.ChunkPartSizeRoot + 1;
                    int coordX        = Mathf.FloorToInt(x / chunkPartSize) - 1;
                    int coordZ        = Mathf.FloorToInt(z / chunkPartSize) - 1;

                    Vector2 chunkPartCoords = terrainChunk.Coord * meshSettings.ChunkPartSizeRoot + new Vector2(coordX, -coordZ);

                    tempObjectPoints.Add(new ObjectPoint(position, rotation, resourcePoint.biomeId, resourcePoint.worldResourcePrefabId, chunkPartCoords.x, chunkPartCoords.y));
                }

                return(tempObjectPoints.ToArray());
            }
        }
Esempio n. 5
0
        private static void FillChunkParts(int uniformSize, ref Dictionary <Vector2, TerrainChunkPart> chunkParts, MeshSettings meshSettings, ResourceMapSettings resourceMapSettings, BiomeMap biomeMap, HeightMap heightMap, TerrainChunk terrainChunk)
        {
            ObjectPoint[] objectPoints = CreateObjectPoints(uniformSize, meshSettings, resourceMapSettings, biomeMap, heightMap, terrainChunk);

            // Fill chunk parts
            for (int i = 0; i < objectPoints.Length; i++)
            {
                Vector2          chunkPartCoords  = new Vector2(objectPoints[i].chunkPartCoordX, objectPoints[i].chunkPartCoordZ);
                TerrainChunkPart terrainChunkPart = chunkParts[chunkPartCoords];

                terrainChunkPart.AddObjectPoint(objectPoints[i]);
            }
        }
Esempio n. 6
0
        private static Dictionary <Vector2, TerrainChunkPart> CreateChunkParts(int uniformSize, MeshSettings meshSettings, TerrainChunk terrainChunk)
        {
            Dictionary <Vector2, TerrainChunkPart> chunkParts = new Dictionary <Vector2, TerrainChunkPart>();

            int chunkRangeHalf = Mathf.FloorToInt(meshSettings.ChunkPartSizeRoot / 2f); // ONLY WORKS FOR UNEVEN NUMBERS AT THE MOMENT

            for (int x = -chunkRangeHalf; x <= chunkRangeHalf; x++)
            {
                for (int z = -chunkRangeHalf; z <= chunkRangeHalf; z++)
                {
                    Vector2 chunkPartCoord    = terrainChunk.Coord * meshSettings.ChunkPartSizeRoot + new Vector2(x, z);
                    Vector3 partWorldPosition = new Vector3(terrainChunk.Bounds.size.x / meshSettings.ChunkPartSizeRoot * chunkPartCoord.x, 0f, terrainChunk.Bounds.size.y / meshSettings.ChunkPartSizeRoot * chunkPartCoord.y);

                    chunkParts.Add(chunkPartCoord, new TerrainChunkPart(chunkPartCoord, partWorldPosition, terrainChunk));
                }
            }

            return(chunkParts);
        }
Esempio n. 7
0
        /// <summary>
        /// Generates a <see cref="DataMap"/> that consists of a heightmap, biomeMap and resourceMap based on a single size. Divides the resourceMap in <see cref="DataMap.ChunkParts"/> based on <see cref="MeshSettings.ChunkPartSizeRoot"/>
        /// </summary>
        /// <param name="terrainChunk">The terrain chunk that requested the DataMap.</param>
        /// <returns></returns>
        public static DataMap GenerateDataMap(MeshSettings meshSettings, HeightMapSettings heightMapSettings, BiomeMapSettings biomeMapSettings, ResourceMapSettings resourceMapSettings, TerrainChunk terrainChunk)
        {
            int size        = meshSettings.NumVertsPerLine;
            int uniformSize = size - 2;

            // Generate data maps
            HeightMap heightMap = HeightMapGenerator.GenerateHeightMap(size, heightMapSettings, terrainChunk.SampleCenter);
            BiomeMap  biomeMap  = BiomeMapGenerator.GenerateBiomeMap(uniformSize, biomeMapSettings, terrainChunk.SampleCenter);

            // Create chunk parts
            Dictionary <Vector2, TerrainChunkPart> chunkParts = CreateChunkParts(uniformSize, meshSettings, terrainChunk);

            FillChunkParts(uniformSize, ref chunkParts, meshSettings, resourceMapSettings, biomeMap, heightMap, terrainChunk);

            return(new DataMap(uniformSize, heightMap, biomeMap, chunkParts));
        }
 public TerrainChunkPart(Vector2 coord, Vector3 worldPosition, TerrainChunk terrainChunk)
 {
     this.Coord         = coord;
     this.WorldPosition = worldPosition;
     this.terrainChunk  = terrainChunk;
 }