73 lines
2.6 KiB
C#
73 lines
2.6 KiB
C#
using UnityEngine;
|
|
|
|
namespace Ashwild.GrassClearer
|
|
{
|
|
public class GrassClearer : MonoBehaviour
|
|
{
|
|
// Singleton pour un accès direct sans FindObjectOfType
|
|
public static GrassClearer Instance { get; private set; }
|
|
|
|
void Awake()
|
|
{
|
|
Instance = this;
|
|
}
|
|
|
|
// Appelle ça quand un bâtiment est posé.
|
|
// worldCenter = centre du sol, sizeWorld = (largeur, profondeur) en mètres
|
|
public void ClearGrassRect(Vector3 worldCenter, Vector2 sizeWorld)
|
|
{
|
|
Terrain terrain = GetTerrainAt(worldCenter);
|
|
if (terrain == null) return;
|
|
|
|
TerrainData data = terrain.terrainData;
|
|
int detailW = data.detailWidth;
|
|
int detailH = data.detailHeight;
|
|
|
|
// Position relative au terrain, normalisée 0-1
|
|
Vector3 local = worldCenter - terrain.transform.position;
|
|
float normX = local.x / data.size.x;
|
|
float normZ = local.z / data.size.z;
|
|
|
|
int cx = Mathf.RoundToInt(normX * detailW);
|
|
int cz = Mathf.RoundToInt(normZ * detailH);
|
|
|
|
// Demi-taille en cellules de detail
|
|
int radX = Mathf.CeilToInt((sizeWorld.x * 0.5f / data.size.x) * detailW);
|
|
int radZ = Mathf.CeilToInt((sizeWorld.y * 0.5f / data.size.z) * detailH);
|
|
|
|
int xMin = Mathf.Clamp(cx - radX, 0, detailW - 1);
|
|
int xMax = Mathf.Clamp(cx + radX, 0, detailW - 1);
|
|
int zMin = Mathf.Clamp(cz - radZ, 0, detailH - 1);
|
|
int zMax = Mathf.Clamp(cz + radZ, 0, detailH - 1);
|
|
|
|
int w = xMax - xMin + 1;
|
|
int h = zMax - zMin + 1;
|
|
if (w <= 0 || h <= 0) return;
|
|
|
|
// On vide TOUTES les couches de details (herbe + fleurs) dans la zone
|
|
int numLayers = data.detailPrototypes.Length;
|
|
for (int layer = 0; layer < numLayers; layer++)
|
|
{
|
|
int[,] block = data.GetDetailLayer(xMin, zMin, w, h, layer);
|
|
for (int y = 0; y < h; y++)
|
|
for (int x = 0; x < w; x++)
|
|
block[y, x] = 0;
|
|
data.SetDetailLayer(xMin, zMin, layer, block);
|
|
}
|
|
}
|
|
|
|
// Trouve le terrain qui contient cette position (gère le multi-terrain)
|
|
Terrain GetTerrainAt(Vector3 worldPos)
|
|
{
|
|
foreach (var t in Terrain.activeTerrains)
|
|
{
|
|
Vector3 l = worldPos - t.transform.position;
|
|
TerrainData d = t.terrainData;
|
|
if (l.x >= 0 && l.x <= d.size.x && l.z >= 0 && l.z <= d.size.z)
|
|
return t;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|