Beispiel #1
0
        /// <summary>
        /// Generates block types with hp and hp level.
        /// Chunks and their objects (if first run = true).
        /// And calculates faces.
        /// </summary>
        public IEnumerator CreateWorld(bool firstRun, Action callback)
        {
            _terrainGenerator.Initialize(Settings);
            _meshGenerator.Initialize(Settings);

            _stopwatch.Restart();
            ResetProgressBarVariables();

            ProgressDescription = "Initialization...";
            Status            = WorldGeneratorStatus.NotReady;
            Blocks            = new BlockData[Settings.WorldSizeX * CHUNK_SIZE, WORLD_SIZE_Y *CHUNK_SIZE, Settings.WorldSizeZ *CHUNK_SIZE];
            AlreadyGenerated += _progressStep;
            yield return(null);

            if (Settings.ComputingAcceleration == ComputingAcceleration.UnityJobSystem)
            {
                ProgressDescription = "Calculating heights...";
                var heights = _terrainGenerator.CalculateHeightsJobSystem();
                AlreadyGenerated += _progressStep;
                yield return(null);

                ProgressDescription = "Calculating block types...";
                var types = _terrainGenerator.CalculateBlockTypes(heights);
                AlreadyGenerated += _progressStep;
                yield return(null);

                ProgressDescription = "Job output deflattenization...";
                DeflattenizeOutput(ref types);
                AlreadyGenerated += _progressStep;
                yield return(null);
            }
            else if (Settings.ComputingAcceleration == ComputingAcceleration.PureCSParallelisation)
            {
                ProgressDescription = "Calculating block types...";
                _terrainGenerator.CalculateBlockTypesParallel();
                AlreadyGenerated += _progressStep * 3;
                yield return(null);
            }

            if (Settings.IsWater)
            {
                ProgressDescription = "Generating water...";
                _terrainGenerator.AddWater(ref Blocks);
            }
            AlreadyGenerated += _progressStep;
            yield return(null);

            ProgressDescription = "Generating trees...";
            _terrainGenerator.AddTreesParallel(Settings.TreeProbability);
            AlreadyGenerated += _progressStep;
            yield return(null);

            ProgressDescription = "Chunk data initialization...";
            if (firstRun)
            {
                _worldScene = SceneManager.CreateScene(name);
            }

            // chunkData need to be initialized earlier in order to allow main loop iterate over chunks before their meshes are ready
            // thanks to this we can display chunk as soon as they become ready
            Chunks = new ChunkData[Settings.WorldSizeX, WORLD_SIZE_Y, Settings.WorldSizeZ];
            for (int x = 0; x < Settings.WorldSizeX; x++)
            {
                for (int z = 0; z < Settings.WorldSizeZ; z++)
                {
                    for (int y = 0; y < WORLD_SIZE_Y; y++)
                    {
                        Chunks[x, y, z] = new ChunkData(new Vector3Int(x, y, z), new Vector3Int(x * CHUNK_SIZE, y * CHUNK_SIZE, z * CHUNK_SIZE));
                    }
                }
            }

            ChunkObjects = new ChunkObject[Settings.WorldSizeX, WORLD_SIZE_Y, Settings.WorldSizeZ];
            yield return(null);

            ProgressDescription = "Calculating faces...";
            _meshGenerator.CalculateFaces(ref Blocks);
            AlreadyGenerated += _progressStep;
            yield return(null);

            ProgressDescription = "World boundaries check...";
            _meshGenerator.WorldBoundariesCheck(ref Blocks);
            AlreadyGenerated += _progressStep;
            yield return(null);

            ProgressDescription = "Creating chunks...";
            // create chunk objects one by one
            for (int x = 0; x < Settings.WorldSizeX; x++)
            {
                for (int z = 0; z < Settings.WorldSizeZ; z++)
                {
                    for (int y = 0; y < WORLD_SIZE_Y; y++)
                    {
                        ChunkData chunkData = Chunks[x, y, z];
                        _meshGenerator.CalculateMeshes(ref Blocks, chunkData.Position, out Mesh terrainMesh, out Mesh waterMesh);

                        if (firstRun)
                        {
                            var chunkObject = new ChunkObject();
                            CreateChunkGameObjects(ref chunkData, ref chunkObject, terrainMesh, waterMesh);
                            SceneManager.MoveGameObjectToScene(chunkObject.Terrain.gameObject, _worldScene);
                            SceneManager.MoveGameObjectToScene(chunkObject.Water.gameObject, _worldScene);
                            ChunkObjects[x, y, z] = chunkObject;
                        }
                        else
                        {
                            SetMeshesAndCollider(ref chunkData, ref ChunkObjects[x, y, z], terrainMesh, waterMesh);
                        }

                        Chunks[x, y, z].Status = ChunkStatus.NeedToBeRedrawn;
                        AlreadyGenerated++;

                        yield return(null); // give back control
                    }
                }
            }

            Status            = WorldGeneratorStatus.AllReady;
            AlreadyGenerated += _progressStep;

            _stopwatch.Stop();
            UnityEngine.Debug.Log($"It took {_stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond} ms to generate the world.");

            ProgressDescription = "Generation Completed";
            callback?.Invoke();
        }
Beispiel #2
0
        /// <summary>
        /// Generates block types with hp and hp level.
        /// Chunks and their objects (if first run = true).
        /// And calculates faces.
        /// </summary>
        public IEnumerator CreateWorld(bool firstRun, Action callback)
        {
            MainController.InitializeOnWorldSizeChange();

            _stopwatch.Restart();
            ResetProgressBarVariables();

            ProgressDescription = "Initialization...";
            Status = WorldGeneratorStatus.NotReady;
            GlobalVariables.Blocks = new BlockData[
                GlobalVariables.Settings.WorldSizeX * Constants.CHUNK_SIZE,
                Constants.WORLD_SIZE_Y *Constants.CHUNK_SIZE, GlobalVariables.Settings.WorldSizeZ *Constants.CHUNK_SIZE];

            AlreadyGenerated += _progressStep;
            yield return(null); // return control

            ProgressDescription = "Calculating block types...";
            TerrainGenerationAbstractionLayer.CalculateBlockTypes();
            AlreadyGenerated += _progressStep;
            yield return(null); // return control to update the UI

            if (GlobalVariables.Settings.IsWater)
            {
                ProgressDescription = "Generating water...";
                TerrainGenerationAbstractionLayer.AddWater();
            }
            AlreadyGenerated += _progressStep;
            yield return(null); // return control

            ProgressDescription = "Generating trees...";
            TerrainGenerationAbstractionLayer.AddTrees();
            AlreadyGenerated += _progressStep;
            yield return(null); // return control

            ProgressDescription = "Chunk data initialization...";
            if (firstRun)
            {
                _worldScene = SceneManager.CreateScene(name);
            }

            // chunkData need to be initialized earlier in order to allow main loop iterate over chunks before their meshes are ready
            // thanks to this we can display chunk as soon as they become ready
            GlobalVariables.Chunks = new ChunkData[GlobalVariables.Settings.WorldSizeX, Constants.WORLD_SIZE_Y, GlobalVariables.Settings.WorldSizeZ];
            for (int x = 0; x < GlobalVariables.Settings.WorldSizeX; x++)
            {
                for (int z = 0; z < GlobalVariables.Settings.WorldSizeZ; z++)
                {
                    for (int y = 0; y < Constants.WORLD_SIZE_Y; y++)
                    {
                        GlobalVariables.Chunks[x, y, z] = new ChunkData(
                            coord: new ReadonlyVector3Int(x, y, z),
                            position: new ReadonlyVector3Int(x * Constants.CHUNK_SIZE, y * Constants.CHUNK_SIZE, z * Constants.CHUNK_SIZE));
                    }
                }
            }

            ChunkObjects = new ChunkObject[GlobalVariables.Settings.WorldSizeX, Constants.WORLD_SIZE_Y, GlobalVariables.Settings.WorldSizeZ];
            yield return(null); // return control

            ProgressDescription = "Calculating faces...";
            MeshGenerationAbstractionLayer.CalculateFaces();
            AlreadyGenerated += _progressStep;
            yield return(null); // return control

            ProgressDescription = "World boundaries check...";
            MeshGenerationAbstractionLayer.WorldBoundariesCheck();
            AlreadyGenerated += _progressStep;
            yield return(null); // return control

            ProgressDescription = "Creating chunks...";
            // create chunk objects one by one
            for (int x = 0; x < GlobalVariables.Settings.WorldSizeX; x++)
            {
                for (int z = 0; z < GlobalVariables.Settings.WorldSizeZ; z++)
                {
                    for (int y = 0; y < Constants.WORLD_SIZE_Y; y++)
                    {
                        ChunkData chunkData = GlobalVariables.Chunks[x, y, z];
                        MeshGenerationAbstractionLayer.CalculateMeshes(in chunkData.Position, out Mesh terrainMesh, out Mesh waterMesh);

                        if (firstRun)
                        {
                            var chunkObject = new ChunkObject();
                            CreateChunkGameObjects(ref chunkData, ref chunkObject, terrainMesh, waterMesh);
                            SceneManager.MoveGameObjectToScene(chunkObject.Terrain.gameObject, _worldScene);
                            SceneManager.MoveGameObjectToScene(chunkObject.Water.gameObject, _worldScene);
                            ChunkObjects[x, y, z] = chunkObject;
                        }
                        else
                        {
                            SetMeshesAndCollider(ref chunkData, ref ChunkObjects[x, y, z], terrainMesh, waterMesh);
                        }

                        GlobalVariables.Chunks[x, y, z].Status = ChunkStatus.NeedToBeRedrawn;
                        AlreadyGenerated++;

                        yield return(null); // return control
                    }
                }
            }

            Status            = WorldGeneratorStatus.AllReady;
            AlreadyGenerated += _progressStep;

            _stopwatch.Stop();
            UnityEngine.Debug.Log($"It took {_stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond} ms to generate the world.");

            ProgressDescription = $"Generation Completed {_stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond} ms";
            callback?.Invoke();
        }
Beispiel #3
0
        /// <summary>
        /// Generates block types with hp and hp level.
        /// Chunks and their objects (if first run = true).
        /// And calculates faces.
        /// </summary>
        public IEnumerator LoadWorld(bool firstRun, Action callback)
        {
            ResetProgressBarVariables();
            _stopwatch.Restart();

            ProgressDescription = "Loading data...";
            Status = WorldGeneratorStatus.NotReady;
            var          storage = new PersistentStorage(CHUNK_SIZE);
            SaveGameData save    = storage.LoadGame();

            Settings.WorldSizeX  = save.WorldSizeX;
            Settings.WorldSizeZ  = save.WorldSizeZ;
            PlayerLoadedPosition = save.PlayerPosition;
            PlayerLoadedRotation = save.PlayerRotation;
            AlreadyGenerated    += _progressStep;
            yield return(null); // give back control

            ProgressDescription = "Creating game objects...";
            if (firstRun)
            {
                _worldScene = SceneManager.CreateScene(name);
            }

            Blocks            = save.Blocks;
            Status            = WorldGeneratorStatus.TerrainReady;
            AlreadyGenerated += _progressStep;
            yield return(null); // give back control

            if (firstRun)
            {
                ProgressDescription = "Chunk data initialization...";
                // chunkData need to be initialized earlier in order to allow main loop iterate over chunks before their meshes are ready
                // thanks to this we can display chunk as soon as they become ready
                Chunks = new ChunkData[Settings.WorldSizeX, WORLD_SIZE_Y, Settings.WorldSizeZ];
                for (int x = 0; x < Settings.WorldSizeX; x++)
                {
                    for (int z = 0; z < Settings.WorldSizeZ; z++)
                    {
                        for (int y = 0; y < WORLD_SIZE_Y; y++)
                        {
                            Chunks[x, y, z] = new ChunkData(
                                new Vector3Int(x, y, z),
                                new Vector3Int(x * CHUNK_SIZE, y * CHUNK_SIZE, z * CHUNK_SIZE));
                        }
                    }
                }

                ChunkObjects      = new ChunkObject[Settings.WorldSizeX, WORLD_SIZE_Y, Settings.WorldSizeZ];
                AlreadyGenerated += _progressStep;
                yield return(null); // give back control
            }

            ProgressDescription = "Calculating faces...";
            _meshGenerator.CalculateFaces(ref Blocks);
            AlreadyGenerated += _progressStep;
            yield return(null); // give back control

            ProgressDescription = "World boundaries check...";
            _meshGenerator.WorldBoundariesCheck(ref Blocks);
            Status            = WorldGeneratorStatus.FacesReady;
            AlreadyGenerated += _progressStep;
            yield return(null); // give back control

            ProgressDescription = "Creating chunks...";
            // create chunk objects one by one
            for (int x = 0; x < Settings.WorldSizeX; x++)
            {
                for (int z = 0; z < Settings.WorldSizeZ; z++)
                {
                    for (int y = 0; y < WORLD_SIZE_Y; y++)
                    {
                        ChunkData chunkData = Chunks[x, y, z];
                        _meshGenerator.CalculateMeshes(ref Blocks, chunkData.Position, out Mesh terrainMesh, out Mesh waterMesh);

                        if (firstRun)
                        {
                            var chunkObject = new ChunkObject();
                            CreateChunkGameObjects(ref chunkData, ref chunkObject, terrainMesh, waterMesh);
                            SceneManager.MoveGameObjectToScene(chunkObject.Terrain.gameObject, _worldScene);
                            SceneManager.MoveGameObjectToScene(chunkObject.Water.gameObject, _worldScene);
                            ChunkObjects[x, y, z] = chunkObject;
                        }
                        else
                        {
                            SetMeshesAndCollider(ref chunkData, ref ChunkObjects[x, y, z], terrainMesh, waterMesh);
                        }

                        Chunks[x, y, z].Status = ChunkStatus.NeedToBeRedrawn;
                        AlreadyGenerated++;

                        yield return(null); // give back control
                    }
                }
            }

            Status = WorldGeneratorStatus.AllReady;

            _stopwatch.Stop();
            UnityEngine.Debug.Log($"It took {_stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond} ms to load all terrain.");

            AlreadyGenerated    = TerrainProgressSteps + MeshProgressSteps; // hardcoded end indicator
            ProgressDescription = "Game Load Completed";

            callback?.Invoke();
        }