83 lines
2.7 KiB
C#
83 lines
2.7 KiB
C#
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
public class TerrainGeneratorOperation : IWorldGeneratorOperation
|
|
{
|
|
[InjectService]
|
|
private GameConfig _config;
|
|
|
|
[InjectService]
|
|
private IScene _scene;
|
|
|
|
[InjectService]
|
|
private WorldRenderingState _renderingState;
|
|
|
|
public async UniTask Execute(World world)
|
|
{
|
|
var generators = new List<ChunkMeshGenerator>
|
|
{
|
|
new TerrainChunkMeshGenerator(world, _config),
|
|
new GrassChunkMeshGenerator(world, _config),
|
|
new CropsChunkMeshGenerator(world, _config)
|
|
};
|
|
|
|
var chunkSize = _config.WorldGen.ChunkSize;
|
|
var horizontalResolution = Mathf.CeilToInt((float)world.Size.x / chunkSize);
|
|
var verticalResolution = Mathf.CeilToInt((float)world.Size.y / chunkSize);
|
|
|
|
for (var x = 0; x < horizontalResolution; x++)
|
|
for (var y = 0; y < verticalResolution; y++)
|
|
{
|
|
var chunk = CreateChunk(x, y);
|
|
|
|
foreach (var generator in generators) generator.InitializeChunk(chunk);
|
|
|
|
_renderingState.AddTerrainChunk(chunk);
|
|
}
|
|
|
|
await UniTask.NextFrame();
|
|
|
|
var batch = new List<TerrainChunk>(_config.WorldGen.ChunkGenerationBatchCount);
|
|
var count = 0;
|
|
|
|
while (count < _renderingState.TerrainChunks.Count)
|
|
{
|
|
batch.Clear();
|
|
for (var i = 0; i < _config.WorldGen.ChunkGenerationBatchCount; i++)
|
|
{
|
|
batch.Add(_renderingState.TerrainChunks[count]);
|
|
if (++count >= _renderingState.TerrainChunks.Count) break;
|
|
}
|
|
|
|
foreach (var generator in generators) generator.BeginGeneratingChunks(batch);
|
|
|
|
foreach (var generator in generators) await generator.Wait();
|
|
|
|
foreach (var generator in generators)
|
|
{
|
|
generator.EndGeneratingChunks();
|
|
await UniTask.NextFrame();
|
|
}
|
|
}
|
|
}
|
|
|
|
private TerrainChunk CreateChunk(int x, int y)
|
|
{
|
|
var chunk = new TerrainChunk
|
|
{
|
|
Coords = new int2(x, y),
|
|
Root = new GameObject($"Chunk_{x}_{y}")
|
|
};
|
|
|
|
chunk.Root.transform.SetParent(_scene.SceneFolders.TerrainChunks);
|
|
chunk.GrassLODs = new TerrainChunk.RenderData[_config.Terrain.GrassLODs.Length];
|
|
chunk.CropsLODs = new TerrainChunk.RenderData[_config.Terrain.CropsLODs.Length];
|
|
|
|
return chunk;
|
|
}
|
|
}
|
|
} |