using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlanetDeath : MonoBehaviour { [Header("Текстури -- Тропосфера")] public Texture2D tropo100; public Texture2D tropo70; public Texture2D tropo50; public Texture2D tropo30; public Texture2D tropo0; [Header("Текстури -- Стратосфера")] public Texture2D strato100; public Texture2D strato70; public Texture2D strato50; public Texture2D strato30; public Texture2D strato0; [Header("Мертва планета")] public Texture2D deadPlanetTexture; [Header("Текстури -- Термосфера")] public Texture2D thermo100; public Texture2D thermo70; public Texture2D thermo50; public Texture2D thermo30; public Texture2D thermo0; [Header("Рівні шарів")] [Range(0f, 1f)] public float troposphereLevel = 1f; [Range(0f, 1f)] public float stratosphereLevel = 1f; [Range(0f, 1f)] public float mesosphereLevel = 1f; [Range(0f, 1f)] public float thermosphereLevel = 1f; [Range(0f, 1f)] public float exosphereLevel = 1f; [Header("Зв'язки")] public TroposphereEffects troposphere; public GameObject troposphereLayerObject; public GameObject stratosphereLayerObject; public GameObject mesosphereLayerObject; public GameObject thermosphereLayerObject; public GameObject exosphereLayerObject; [Header("Випаровування")] public bool showEvaporation = true; public Material evaporationMaterial; private Renderer planetRenderer; private Material mat; private ParticleSystem evaporationSystem; private Texture2D currentBlended; private float prevTropo = -1f; private float prevStrato = -1f; private float prevThermo = -1f; void Start() { planetRenderer = GetComponent(); mat = planetRenderer.material; currentBlended = new Texture2D(tropo100.width, tropo100.height, TextureFormat.RGB24, false); if (showEvaporation) CreateEvaporationEffect(); } public void ResetTextureCache() { prevTropo = -1f; prevStrato = -1f; prevThermo = -1f; } void Update() { if (mat == null) return; UpdateTexture(); UpdateAtmosphereLayers(); UpdateWeather(); UpdateEvaporation(); StratosphereDeath strato = stratosphereLayerObject?.GetComponent(); if (strato != null) strato.stratosphereLevel = stratosphereLevel; MesosphereEffects meso = mesosphereLayerObject?.GetComponent(); if (meso != null) meso.mesosphereLevel = mesosphereLevel; ThermosphereEffects thermo = thermosphereLayerObject?.GetComponent(); if (thermo != null) thermo.thermosphereLevel = thermosphereLevel; ExosphereEffects exo = exosphereLayerObject?.GetComponent(); if (exo != null) exo.exosphereLevel = exosphereLevel; } void UpdateTexture() { bool isDead = troposphereLevel <= 0f || stratosphereLevel <= 0f || thermosphereLevel <= 0f; if (isDead) { if (deadPlanetTexture != null) mat.mainTexture = deadPlanetTexture; UpdateLayerMaterial(troposphereLayerObject, 0f); UpdateLayerMaterial(stratosphereLayerObject, 0f); UpdateLayerMaterial(mesosphereLayerObject, 0f); UpdateLayerMaterial(thermosphereLayerObject, 0f); UpdateLayerMaterial(exosphereLayerObject, 0f); return; } else { troposphereLayerObject?.SetActive(true); stratosphereLayerObject?.SetActive(true); mesosphereLayerObject?.SetActive(true); thermosphereLayerObject?.SetActive(true); exosphereLayerObject?.SetActive(true); } if (Mathf.Approximately(troposphereLevel, prevTropo) && Mathf.Approximately(stratosphereLevel, prevStrato) && Mathf.Approximately(thermosphereLevel, prevThermo)) return; prevTropo = troposphereLevel; prevStrato = stratosphereLevel; prevThermo = thermosphereLevel; Texture2D tropoTex = GetLayerTexture(troposphereLevel, tropo100, tropo70, tropo50, tropo30, tropo0); Texture2D stratoTex = GetLayerTexture(stratosphereLevel, strato100, strato70, strato50, strato30, strato0); Texture2D thermoTex = GetLayerTexture(thermosphereLevel, thermo100, thermo70, thermo50, thermo30, thermo0); if (tropoTex == null || stratoTex == null) return; Color[] tropoPixels = tropoTex.GetPixels(); Color[] stratoPixels = stratoTex.GetPixels(); Color[] thermoPixels = thermoTex != null ? thermoTex.GetPixels() : null; Color[] basePixels = tropo100.GetPixels(); Color[] output = new Color[tropoPixels.Length]; for (int i = 0; i < output.Length; i++) { Color col = basePixels[i]; if (troposphereLevel < 1f) col = Color.Lerp(col, tropoPixels[i], 1f - troposphereLevel); if (stratosphereLevel < 1f) col = Color.Lerp(col, stratoPixels[i], 1f - stratosphereLevel); if (thermosphereLevel < 1f && thermoPixels != null) col = Color.Lerp(col, thermoPixels[i], 1f - thermosphereLevel); output[i] = col; } currentBlended.SetPixels(output); currentBlended.Apply(); mat.mainTexture = currentBlended; } Texture2D GetLayerTexture(float level, Texture2D t100, Texture2D t70, Texture2D t50, Texture2D t30, Texture2D t0) { if (level >= 0.85f) return Blend(t100, t70, Mathf.InverseLerp(1.0f, 0.85f, level)); else if (level >= 0.6f) return Blend(t70, t50, Mathf.InverseLerp(0.85f, 0.6f, level)); else if (level >= 0.4f) return Blend(t50, t30, Mathf.InverseLerp(0.6f, 0.4f, level)); else return Blend(t30, t0, Mathf.InverseLerp(0.4f, 0f, level)); } Texture2D Blend(Texture2D a, Texture2D b, float t) { if (t <= 0f || a == null) return a; if (t >= 1f || b == null) return b; if (t < 0.5f) return a; return b; } void UpdateAtmosphereLayers() { bool isDead = troposphereLevel <= 0f || stratosphereLevel <= 0f || thermosphereLevel <= 0f || exosphereLevel <= 0f; if (isDead) { UpdateLayerMaterial(troposphereLayerObject, 0f); UpdateLayerMaterial(stratosphereLayerObject, 0f); UpdateLayerMaterial(mesosphereLayerObject, 0f); UpdateLayerMaterial(thermosphereLayerObject, 0f); UpdateLayerMaterial(exosphereLayerObject, 0f); return; } UpdateLayerMaterial(troposphereLayerObject, troposphereLevel); UpdateLayerMaterial(stratosphereLayerObject, stratosphereLevel); UpdateLayerMaterial(mesosphereLayerObject, mesosphereLevel); UpdateLayerMaterial(thermosphereLayerObject, thermosphereLevel); UpdateLayerMaterial(exosphereLayerObject, exosphereLevel); } void UpdateLayerMaterial(GameObject layerObj, float level) { if (layerObj == null) return; Renderer r = layerObj.GetComponent(); if (r == null) return; Material layerMat = r.material; layerMat.SetFloat("_RimIntensity", Mathf.Lerp(0f, 2.5f, level)); layerMat.SetFloat("_CoreIntensity", Mathf.Lerp(0f, 0.4f, level)); } void UpdateWeather() { if (troposphere == null) return; bool isDead = troposphereLevel <= 0f || stratosphereLevel <= 0f || mesosphereLevel <= 0f || thermosphereLevel <= 0f || exosphereLevel <= 0f; if (isDead) { troposphere.SetRainEnabled(false); troposphere.SetCloudsEnabled(false); return; } float combinedLevel = Mathf.Min(troposphereLevel, stratosphereLevel); if (combinedLevel < 0.5f) troposphere.SetRainEnabled(false); else troposphere.SetRainEnabled(troposphereLevel >= 0.8f); if (combinedLevel < 0.4f) troposphere.SetCloudsEnabled(false); else troposphere.SetCloudsEnabled(troposphereLevel >= 0.6f); if (combinedLevel < 0.2f) troposphere.gameObject.SetActive(false); else troposphere.gameObject.SetActive(true); } void UpdateEvaporation() { if (evaporationSystem == null) return; var emission = evaporationSystem.emission; var main = evaporationSystem.main; if (troposphereLevel <= 0.5f && troposphereLevel > 0.05f) { float t = Mathf.InverseLerp(0.5f, 0.05f, troposphereLevel); emission.rateOverTime = Mathf.Lerp(100f, 10000f, t); main.startSize = new ParticleSystem.MinMaxCurve( Mathf.Lerp(0.02f, 0.15f, t), Mathf.Lerp(0.08f, 0.3f, t) ); } else { emission.rateOverTime = 0f; } } void CreateEvaporationEffect() { GameObject obj = new GameObject("EvaporationParticles"); obj.transform.parent = null; obj.transform.position = this.transform.position; evaporationSystem = obj.AddComponent(); var main = evaporationSystem.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 20000; main.startLifetime = new ParticleSystem.MinMaxCurve(2f, 5f); main.startSpeed = new ParticleSystem.MinMaxCurve(1f, 3f); main.startSize = new ParticleSystem.MinMaxCurve(0.05f, 0.15f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.4f, 0.7f, 1.0f, 1f), new Color(0.6f, 0.85f, 1.0f, 0.8f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = evaporationSystem.emission; emission.rateOverTime = 0f; var shape = evaporationSystem.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Sphere; shape.radius = 6.4f; shape.radiusThickness = 0f; var colorOverLifetime = evaporationSystem.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(0.4f, 0.7f, 1.0f), 0f), new GradientColorKey(new Color(0.8f, 0.9f, 1.0f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var psRenderer = evaporationSystem.GetComponent(); psRenderer.renderMode = ParticleSystemRenderMode.Billboard; psRenderer.sortingFudge = 5f; if (evaporationMaterial != null) psRenderer.material = evaporationMaterial; evaporationSystem.Play(); } }