示例#1
0
        /// <summary>
        /// Delegates the generation to the underlying view models.
        /// Displays the generated content using the unity objects
        /// </summary>
        /// <param name="finishAction">The action to invoke when the generation is completed.</param>
        /// <param name="generationStartAction">The action to invoke when a generation starts.</param>
        /// <param name="generationEndAction">The action to invoke when a generation ends.</param>
        /// <param name="cancellationToken">The cancellation token, used to cancel the generation.</param>
        internal async void GenerateAsync(
            Action finishAction,
            OnGenerationStart generationStartAction,
            OnGenerationEnd generationEndAction,
            CancellationToken cancellationToken)
        {
            Reset();
            _finishedGenerations = 0;

            _onGenerationStart = generationStartAction;
            _onGenerationEnd   = generationEndAction;

            // Invokes the finish action
            void OnGenerationFinish() => finishAction?.Invoke();

            // Update the cancellation token of the view models
            terrainViewModel.CancelToken = cancellationToken;
            cityViewModel.CancelToken    = cancellationToken;

            try
            {
                // Generate the terrain
                var(terrainMesh, terrainTexture) = await Task.Run(() => terrainViewModel.Generate(), cancellationToken);

                if (cancellationToken.IsCancellationRequested || terrainMesh == null || terrainTexture == null)
                {
                    // Either the task was cancelled or a terrain value is null, abort.
                    OnGenerationFinish();
                    return;
                }

                // Update component data
                _meshFilter.sharedMesh   = terrainMesh;
                _meshCollider.sharedMesh = terrainMesh;
                _meshRenderer.sharedMaterial.mainTexture = terrainTexture;

                // Update the model's terrain data
                _model.TerrainTexture   = terrainTexture;
                _model.TerrainHeightMap = _meshFilter.sharedMesh.HeightMap();
                _model.TerrainOffset    = _meshFilter.transform.position;

                // Generate a city
                _model.City = await Task.Run(() => cityViewModel.Generate(), cancellationToken);
            }
            catch (TaskCanceledException)
            {
                // A task was canceled, abort
                OnGenerationFinish();
                return;
            }

            if (cancellationToken.IsCancellationRequested || _model.City == null)
            {
                // Either the task was canceled or the city is not valid, abort.
                OnGenerationFinish();
                return;
            }

            // Create game objects based on the world data (terrain and city elements)
            CreateGameObjects(cancellationToken);

            // Invoke the finish action
            OnGenerationFinish();
        }