Files
2026-05-21 16:04:49 +02:00

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;
}
}
}