320 lines
11 KiB
C#
320 lines
11 KiB
C#
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<Renderer>();
|
|
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<StratosphereDeath>();
|
|
if (strato != null) strato.stratosphereLevel = stratosphereLevel;
|
|
|
|
MesosphereEffects meso = mesosphereLayerObject?.GetComponent<MesosphereEffects>();
|
|
if (meso != null) meso.mesosphereLevel = mesosphereLevel;
|
|
|
|
ThermosphereEffects thermo = thermosphereLayerObject?.GetComponent<ThermosphereEffects>();
|
|
if (thermo != null) thermo.thermosphereLevel = thermosphereLevel;
|
|
|
|
ExosphereEffects exo = exosphereLayerObject?.GetComponent<ExosphereEffects>();
|
|
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<Renderer>();
|
|
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<ParticleSystem>();
|
|
|
|
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<ParticleSystemRenderer>();
|
|
psRenderer.renderMode = ParticleSystemRenderMode.Billboard;
|
|
psRenderer.sortingFudge = 5f;
|
|
if (evaporationMaterial != null)
|
|
psRenderer.material = evaporationMaterial;
|
|
|
|
evaporationSystem.Play();
|
|
}
|
|
}
|