Пример #1
0
    private void GenerateChunks()
    {
        // Which direction is the player pointing in?
        Vector3 pov = Camera.main.transform.rotation * Vector3.forward;

        pov.y = 0;         // Flatten it as we want it to be horizontal

        // Iterate through x, y, z
        for (int x = _playerPos.x - _viewRangeHorizontal - 1; x <= _playerPos.x + _viewRangeHorizontal + 1; ++x)
        {
            for (int z = _playerPos.z - _viewRangeHorizontal - 1; z <= _playerPos.z + _viewRangeHorizontal + 1; ++z)
            {
                Int2 grid = new Int2(x, z);

                // Does column exist?
                if (!_columns.ContainsKey(grid))
                {
                    // Create new data column
                    DataColumn newDataColumn = new DataColumn(grid);

                    // Store in map
                    _columns[grid] = newDataColumn;
                }

                for (int y = _playerPos.y - _viewRangeVertical - 1; y <= _playerPos.y + _viewRangeVertical + 1; ++y)
                {
                    Int3 pos = new Int3(x, y, z);

                    // Does chunk exist?
                    if (!_chunks.ContainsKey(pos) && Distance(pos, _playerPos) <= _viewRangeHorizontal)
                    {
                        // Create new chunk and get corresponding script
                        GameObject newChunk       = Instantiate(_chunkPrefab, new Vector3(x * _chunkSize, y * _chunkSize, z * _chunkSize), Quaternion.identity);
                        Chunk      newChunkScript = newChunk.GetComponent <Chunk>();

                        DataChunk newDataChunk;

                        if (_offloadChunks.ContainsKey(pos))
                        {
                            // Retrieve from offload
                            newDataChunk = _offloadChunks[pos];

                            // Give data chunk gameobject
                            newDataChunk.SetChunk(newChunkScript);

                            // Remove from offload
                            _offloadChunks.Remove(pos);
                        }
                        else
                        {
                            // Create new data chunk
                            newDataChunk = new DataChunk(pos, newChunkScript);
                        }

                        // Let chunk know its corresponding data chunk and position
                        newChunkScript.LoadData(pos, newDataChunk);

                        // Should chunk render yet?
                        newChunkScript.SetRender(CubeDistance(_playerPos, pos) <= _viewRangeHorizontal);

                        // Get angle difference between vectors
                        Vector3 dir   = pos.Vector() * _chunkSize - Camera.main.transform.position;
                        float   dist  = dir.magnitude;
                        float   diff  = Vector3.Angle(pov, dir);
                        float   final = dist + diff;
                        if (dist < _chunkSize * 2f)                         // Prioritize chunks immediately closest
                        {
                            final = dist;
                        }

                        // Queue chunk for generation
                        _loadQueue.Enqueue(newChunkScript, final);

                        // Store in map
                        _chunks[pos] = newDataChunk;
                    }
                }
            }
        }

        // Are there chunks that need generation?
        if (!_rendering && _loadQueue.Count > 0)
        {
            _rendering = true;
            new Thread(RenderThread).Start();
        }
    }