Files
beyond/Assets/Scripts/GrassDetailScalerByProperties.cs
2024-11-20 15:21:28 +01:00

138 lines
4.6 KiB
C#
Raw Blame History

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GrassDetailScalerByProperties : MonoBehaviour
{
public Terrain terrain; // Referencja do terenu
public List<GrassDetail> grassDetails; // Lista detali trawy do animacji
private bool isAnimating = false;
[System.Serializable]
public class GrassDetail
{
public int detailIndex; // Indeks detalu trawy
public float initialDensity; // Pocz<63>tkowa g<>sto<74><6F> trawy
public float finalDensity; // Ko<4B>cowa g<>sto<74><6F> trawy
public float growthDelay; // Op<4F>nienie przed rozpocz<63>ciem animacji
public float fadeSpeed; // Pr<50>dko<6B><6F> animacji
[HideInInspector]
public float originalDensity; // Oryginalna g<>sto<74><6F> trawy (z edytora)
[HideInInspector]
public int[,] originalDetailLayer; // Oryginalna warstwa detali
}
void Start()
{
// Zapisz pocz<63>tkowe warto<74>ci dla ka<6B>dego rodzaju trawy
TerrainData terrainData = terrain.terrainData;
foreach (var detail in grassDetails)
{
detail.originalDetailLayer = (int[,])terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, detail.detailIndex).Clone();
detail.originalDensity = GetOriginalDensity(detail);
// Przywr<77><72> pocz<63>tkow<6F> g<>sto<74><6F>
SetGrassDensity(detail, detail.originalDensity);
}
}
// Funkcja wywo<77>ywana przez zdarzenie lub inny skrypt
public void GrowGrass()
{
if (!isAnimating)
{
isAnimating = true;
StartCoroutine(GrowGrassCoroutine());
}
}
private IEnumerator GrowGrassCoroutine()
{
// Rozpocznij animacj<63> z op<6F>nieniem dla ka<6B>dego rodzaju trawy
foreach (var detail in grassDetails)
{
// Poczekaj na op<6F>nienie
yield return new WaitForSeconds(detail.growthDelay);
// Animuj g<>sto<74><6F> dla aktualnego rodzaju trawy
while (Mathf.Abs(detail.initialDensity - detail.finalDensity) > 0.01f)
{
detail.initialDensity = Mathf.Lerp(detail.initialDensity, detail.finalDensity, Time.deltaTime * detail.fadeSpeed);
SetGrassDensity(detail, detail.initialDensity);
yield return null; // Czekaj na nast<73>pn<70> klatk<74>
}
// Ustaw dok<6F>adn<64> warto<74><6F> docelow<6F> g<>sto<74>ci
detail.initialDensity = detail.finalDensity;
SetGrassDensity(detail, detail.initialDensity);
}
// Zatrzymaj animacj<63> po osi<73>gni<6E>ciu docelowej g<>sto<74>ci dla wszystkich rodzaj<61>w trawy
isAnimating = false;
}
// Funkcja do ustawiania g<>sto<74>ci trawy
void SetGrassDensity(GrassDetail detail, float density)
{
TerrainData terrainData = terrain.terrainData;
int[,] detailLayer = new int[terrainData.detailWidth, terrainData.detailHeight];
for (int x = 0; x < terrainData.detailWidth; x++)
{
for (int y = 0; y < terrainData.detailHeight; y++)
{
detailLayer[x, y] = Mathf.RoundToInt(detail.originalDetailLayer[x, y] * density);
}
}
terrainData.SetDetailLayer(0, 0, detail.detailIndex, detailLayer);
}
// Funkcja do przywracania oryginalnej g<>sto<74>ci trawy
void RestoreOriginalDensity()
{
if (!terrain)
return;
TerrainData terrainData = terrain.terrainData;
foreach (var detail in grassDetails)
{
terrainData.SetDetailLayer(0, 0, detail.detailIndex, detail.originalDetailLayer);
}
}
// Funkcja do uzyskiwania oryginalnej g<>sto<74>ci z edytora
float GetOriginalDensity(GrassDetail detail)
{
TerrainData terrainData = terrain.terrainData;
int[,] detailLayer = terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, detail.detailIndex);
float totalDensity = 0;
int count = 0;
for (int x = 0; x < terrainData.detailWidth; x++)
{
for (int y = 0; y < terrainData.detailHeight; y++)
{
totalDensity += detailLayer[x, y];
count++;
}
}
return totalDensity / count;
}
void OnDisable()
{
// Przywr<77><72> oryginaln<6C> g<>sto<74><6F> trawy po wy<77><79>czeniu skryptu
RestoreOriginalDensity();
}
void OnApplicationQuit()
{
// Przywr<77><72> oryginaln<6C> g<>sto<74><6F> trawy przed zamkni<6E>ciem aplikacji
RestoreOriginalDensity();
}
}