Ethan_M

Untitled

Nov 1st, 2025
301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.71 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using GamePlay;
  4. using R3;
  5. using Reflex.Attributes;
  6. using UnityEditor;
  7. using UnityEngine;
  8. using UnityEngine.UI;
  9. using VoxelMap;
  10. namespace UI
  11. {
  12.     public class WorldMap : MonoBehaviour
  13.     {
  14.         private const int ColumnPerFrame = 1;
  15.  
  16.         private const string ClearHeight = "ClearHeight";
  17.         private const string UpdateHeight = "UpdateHeight";
  18.         private const string UpdateChunk = "UpdateChunk";
  19.  
  20.         private static readonly int HeightBuffer = Shader.PropertyToID("HeightBuffer");
  21.         private static readonly int VertexBuffer = Shader.PropertyToID("VertexBuffer");
  22.         private static readonly int MapTexture = Shader.PropertyToID("MapTexture");
  23.         private static readonly int MeshPositionOffset = Shader.PropertyToID("MeshPositionOffset");
  24.         private static readonly int ChunkSize = Shader.PropertyToID("ChunkSize");
  25.  
  26.         [SerializeField] private ComputeShader computeShader;
  27.         [SerializeField] private RawImage mapImage;
  28.  
  29.         private MapProvider _mapProvider;
  30.         private EntityContainerService _entityContainer;
  31.  
  32.         private ComputeBuffer _heightBuffer;
  33.         private int _updateHeightKernel;
  34.         private int _updateChunkKernel;
  35.         private int _clearHeightKernel;
  36.  
  37.         [field: SerializeField] public CanvasGroup CanvasGroup { get; private set; }
  38.         public RenderTexture MainTexture { get; private set; }
  39.         private readonly Queue<(int x, int z)> _regeneratingColumns = new Queue<(int x, int z)>();
  40.  
  41.  
  42.         [Inject]
  43.         private void Construct(MapProvider mapProvider)
  44.         {
  45.             _mapProvider = mapProvider;
  46.  
  47.             _heightBuffer = new ComputeBuffer(Chunk.ChunkSizeSquared, sizeof(uint));
  48.             _clearHeightKernel = computeShader.FindKernel(ClearHeight);
  49.             _updateHeightKernel = computeShader.FindKernel(UpdateHeight);
  50.             _updateChunkKernel = computeShader.FindKernel(UpdateChunk);
  51.  
  52.             computeShader.SetFloat(ChunkSize, Chunk.ChunkSize);
  53.         }
  54.  
  55.         public void Initialize()
  56.         {
  57.             if (MainTexture != null)
  58.             {
  59.                 MainTexture.Release();
  60.             }
  61.  
  62.             MainTexture = new RenderTexture(_mapProvider.Map.Width, _mapProvider.Map.Depth, 0, RenderTextureFormat.ARGB32)
  63.             {
  64.                 enableRandomWrite = true,
  65.                 filterMode = FilterMode.Point
  66.             };
  67.  
  68.             MainTexture.Create();
  69.             mapImage.texture = MainTexture;
  70.  
  71.             _mapProvider.Map.ChunkUpdated.Subscribe(OnChunkUpdated).AddTo(_mapProvider.Map);
  72.            
  73.             _regeneratingColumns.Clear();
  74.  
  75.             for (int x = 0; x < _mapProvider.Map.Width / Chunk.ChunkSize; x++)
  76.             {
  77.                 for (var z = 0; z < _mapProvider.Map.Depth / Chunk.ChunkSize; z++)
  78.                 {
  79.                     _regeneratingColumns.Enqueue((x, z));
  80.                 }
  81.             }
  82.         }
  83.  
  84.         private void Update()
  85.         {
  86.             if (_mapProvider.Map == null)
  87.             {
  88.                 return;
  89.             }
  90.            
  91.             for (var i = 0; i < Math.Min(_regeneratingColumns.Count, ColumnPerFrame); i++)
  92.             {
  93.                 (int x, int z) = _regeneratingColumns.Dequeue();
  94.                 RefreshChunkColumn(x, z);
  95.             }
  96.         }
  97.  
  98.         private void RefreshChunkColumn(int x, int z)
  99.         {
  100.             computeShader.SetBuffer(_clearHeightKernel, HeightBuffer, _heightBuffer);
  101.             computeShader.Dispatch(_clearHeightKernel, Chunk.ChunkSize / 8, Chunk.ChunkSize / 8, 1);
  102.  
  103.             for (var y = 0; y < _mapProvider.Map.Height / Chunk.ChunkSize; y++)
  104.             {
  105.                 int chunkIndex = GetChunkIndex(x, y, z);
  106.                 Chunk chunk = _mapProvider.Map.Chunks[chunkIndex];
  107.  
  108.                 if (chunk.Mesh.vertexCount == 0)
  109.                 {
  110.                     continue;
  111.                 }
  112.  
  113.                 chunk.Mesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
  114.                 using GraphicsBuffer vertexBuffer = chunk.Mesh.GetVertexBuffer(0);
  115.                
  116.                 int quadCount = chunk.Mesh.vertexCount / 4;
  117.                
  118.                 computeShader.SetBuffer(_updateHeightKernel, VertexBuffer, vertexBuffer);
  119.                 computeShader.SetBuffer(_updateHeightKernel, HeightBuffer, _heightBuffer);
  120.                 computeShader.SetFloats(MeshPositionOffset, chunk.Position.x, chunk.Position.y, chunk.Position.z);
  121.                 computeShader.Dispatch(_updateHeightKernel, Mathf.Max(1, quadCount / 16), 1, 1);
  122.                
  123.                 computeShader.SetBuffer(_updateChunkKernel, VertexBuffer, vertexBuffer);
  124.                 computeShader.SetBuffer(_updateChunkKernel, HeightBuffer, _heightBuffer);
  125.                 computeShader.SetTexture(_updateChunkKernel, MapTexture, MainTexture);
  126.                 computeShader.SetFloats(MeshPositionOffset, chunk.Position.x, chunk.Position.y, chunk.Position.z);
  127.                 computeShader.Dispatch(_updateChunkKernel, Mathf.Max(1, quadCount / 16), 1, 1);
  128.             }
  129.         }
  130.  
  131.         private void OnChunkUpdated(Chunk chunk)
  132.         {
  133.             _regeneratingColumns.Enqueue((chunk.Position.x / Chunk.ChunkSize, chunk.Position.z / Chunk.ChunkSize));
  134.         }
  135.  
  136.         private int GetChunkIndex(int x, int y, int z)
  137.         {
  138.             return x * (_mapProvider.Map.Height * _mapProvider.Map.Depth / Chunk.ChunkSizeSquared)
  139.                    + y * (_mapProvider.Map.Depth / Chunk.ChunkSize) + z;
  140.         }
  141.  
  142.         private void OnDestroy()
  143.         {
  144.             _heightBuffer.Release();
  145.             MainTexture.Release();
  146.         }
  147.     }
  148. }
Advertisement
Add Comment
Please, Sign In to add comment