using System.Collections; using System.Collections.Generic; using UnityEngine; public class MarsThermosphereEffects : MonoBehaviour { [Header("Налаштування")] public Material tailMaterial; public Material solarWindMaterial; public Material auroraMaterial; public float planetRadius = 3.39f; public Transform sunTransform; [Range(0f, 1f)] public float thermosphereLevel = 1f; public float previousLevel = 1f; private ParticleSystem tailSystem; private ParticleSystem solarWindSystem; private ParticleSystem auroraSystem; private GameObject auroraGlow; private bool deathTriggered = false; void Update() { if (!Application.isPlaying) return; if (thermosphereLevel >= 1f && previousLevel < 1f) { InitState(); deathTriggered = false; } previousLevel = thermosphereLevel; if (thermosphereLevel <= 0f && !deathTriggered) { deathTriggered = true; StartCoroutine(DeathBurst()); return; } if (deathTriggered) return; UpdateTail(); UpdateSolarWind(); UpdateAurora(); } IEnumerator DeathBurst() { if (tailSystem != null) { var e = tailSystem.emission; e.rateOverTime = 2000f; var m = tailSystem.main; m.startSpeed = new ParticleSystem.MinMaxCurve(20f, 50f); } if (solarWindSystem != null) { var e = solarWindSystem.emission; e.rateOverTime = 3000f; } if (auroraSystem != null) { var e = auroraSystem.emission; e.rateOverTime = 500f; } yield return new WaitForSeconds(2f); if (tailSystem != null) { var e = tailSystem.emission; e.rateOverTime = 0f; } if (solarWindSystem != null) { var e = solarWindSystem.emission; e.rateOverTime = 0f; } if (auroraSystem != null) { var e = auroraSystem.emission; e.rateOverTime = 0f; } } void Awake() { enabled = false; } public void InitState() { if (tailSystem != null) Destroy(tailSystem.gameObject); if (solarWindSystem != null) Destroy(solarWindSystem.gameObject); if (auroraSystem != null) Destroy(auroraSystem.gameObject); if (auroraGlow != null) Destroy(auroraGlow); tailSystem = null; solarWindSystem = null; auroraSystem = null; auroraGlow = null; thermosphereLevel = 1f; previousLevel = 1f; CreateAtmosphericTail(); CreateSolarWind(); CreateAurora(); var e1 = tailSystem.emission; e1.rateOverTime = 0f; var e2 = solarWindSystem.emission; e2.rateOverTime = 0f; var e3 = auroraSystem.emission; e3.rateOverTime = 0f; } Vector3 GetSunDirection() { if (sunTransform != null) return (transform.position - sunTransform.position).normalized; Light[] lights = FindObjectsOfType(); foreach (var l in lights) if (l.type == LightType.Directional) return -l.transform.forward; return Vector3.right; } void CreateAtmosphericTail() { Vector3 sunDir = GetSunDirection(); Vector3 tailDir = sunDir; GameObject obj = new GameObject("MarsTail"); obj.transform.parent = null; obj.transform.position = transform.position; obj.transform.rotation = Quaternion.LookRotation(tailDir); tailSystem = obj.AddComponent(); var main = tailSystem.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 8000; main.startLifetime = new ParticleSystem.MinMaxCurve(4f, 10f); main.startSpeed = new ParticleSystem.MinMaxCurve(3f, 8f); main.startSize = new ParticleSystem.MinMaxCurve(0.05f, 0.2f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.6f, 0.8f, 1f, 0.4f), new Color(0.4f, 0.6f, 1f, 0.2f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = tailSystem.emission; emission.rateOverTime = 0f; var shape = tailSystem.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Sphere; shape.radius = planetRadius * 0.8f; shape.radiusThickness = 1f; var velocityOverLifetime = tailSystem.velocityOverLifetime; velocityOverLifetime.enabled = true; velocityOverLifetime.space = ParticleSystemSimulationSpace.World; velocityOverLifetime.x = new ParticleSystem.MinMaxCurve(tailDir.x * 8f); velocityOverLifetime.y = new ParticleSystem.MinMaxCurve(tailDir.y * 8f); velocityOverLifetime.z = new ParticleSystem.MinMaxCurve(tailDir.z * 8f); var noise = tailSystem.noise; noise.enabled = true; noise.strength = 0.3f; noise.frequency = 0.5f; noise.scrollSpeed = 0.3f; var colorOverLifetime = tailSystem.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(0.6f, 0.8f, 1f), 0f), new GradientColorKey(new Color(0.4f, 0.6f, 1f), 0.5f), new GradientColorKey(new Color(0.2f, 0.3f, 0.8f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(0.4f, 0f), new GradientAlphaKey(0.2f, 0.5f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var renderer = tailSystem.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Stretch; renderer.velocityScale = 0.3f; renderer.lengthScale = 3f; renderer.sortingFudge = 3f; if (tailMaterial != null) renderer.material = tailMaterial; tailSystem.Play(); } void CreateSolarWind() { GameObject obj = new GameObject("MarsSolarWind"); obj.transform.parent = null; obj.transform.position = transform.position; solarWindSystem = obj.AddComponent(); var main = solarWindSystem.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 30000; main.startLifetime = new ParticleSystem.MinMaxCurve(3f, 5f); main.startSpeed = new ParticleSystem.MinMaxCurve(0f, 0f); main.startSize = new ParticleSystem.MinMaxCurve(0.15f, 0.4f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(1f, 0.7f, 0.1f, 1f), new Color(1f, 0.5f, 0.0f, 0.8f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = solarWindSystem.emission; emission.rateOverTime = 800f; var shape = solarWindSystem.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Sphere; shape.radius = planetRadius * 6.5f; shape.radiusThickness = 0.3f; var velocityOverLifetime = solarWindSystem.velocityOverLifetime; velocityOverLifetime.enabled = true; velocityOverLifetime.space = ParticleSystemSimulationSpace.World; velocityOverLifetime.orbitalX = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.orbitalY = new ParticleSystem.MinMaxCurve(12f); velocityOverLifetime.orbitalZ = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.x = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.y = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.z = new ParticleSystem.MinMaxCurve(0f); var colorOverLifetime = solarWindSystem.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.9f, 0.5f), 0f), new GradientColorKey(new Color(1f, 0.7f, 0.3f), 0.5f), new GradientColorKey(new Color(0.8f, 0.5f, 0.2f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0.8f, 0.5f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var renderer = solarWindSystem.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Billboard; renderer.sortingFudge = 2f; if (solarWindMaterial != null) renderer.material = solarWindMaterial; solarWindSystem.Play(); } void CreateAurora() { Vector3 auroraDir = new Vector3(0.5f, -0.8f, 0.3f).normalized; Vector3 auroraPos = transform.position + auroraDir * (planetRadius * 1.05f); GameObject obj = new GameObject("MarsAurora"); obj.transform.parent = null; obj.transform.position = auroraPos; obj.transform.up = auroraDir; auroraSystem = obj.AddComponent(); var main = auroraSystem.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 1000; main.startLifetime = new ParticleSystem.MinMaxCurve(1f, 3f); main.startSpeed = new ParticleSystem.MinMaxCurve(0.5f, 2f); main.startSize = new ParticleSystem.MinMaxCurve(0.1f, 0.4f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.1f, 1f, 0.5f, 0.8f), new Color(0.0f, 0.8f, 1f, 0.5f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = auroraSystem.emission; emission.rateOverTime = 60f; var shape = auroraSystem.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Circle; shape.radius = planetRadius * 0.3f; shape.radiusThickness = 0.5f; var velocityOverLifetime = auroraSystem.velocityOverLifetime; velocityOverLifetime.enabled = true; velocityOverLifetime.space = ParticleSystemSimulationSpace.Local; velocityOverLifetime.x = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.y = new ParticleSystem.MinMaxCurve(2f); velocityOverLifetime.z = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.orbitalX = new ParticleSystem.MinMaxCurve(0f); velocityOverLifetime.orbitalY = new ParticleSystem.MinMaxCurve(4f); velocityOverLifetime.orbitalZ = new ParticleSystem.MinMaxCurve(0f); var colorOverLifetime = auroraSystem.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(0.1f, 1f, 0.5f), 0f), new GradientColorKey(new Color(0.0f, 0.8f, 1f), 0.5f), new GradientColorKey(new Color(0.2f, 0.4f, 1f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(0.8f, 0f), new GradientAlphaKey(0.4f, 0.5f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var noise = auroraSystem.noise; noise.enabled = true; noise.strength = 0.4f; noise.frequency = 0.8f; noise.scrollSpeed = 0.5f; var renderer = auroraSystem.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Billboard; renderer.sortingFudge = 5f; if (auroraMaterial != null) renderer.material = auroraMaterial; auroraSystem.Play(); auroraGlow = new GameObject("AuroraGlow"); auroraGlow.transform.parent = null; auroraGlow.transform.position = auroraPos; Light glow = auroraGlow.AddComponent(); glow.type = LightType.Point; glow.color = new Color(0.1f, 1f, 0.5f); glow.intensity = 0f; glow.range = planetRadius * 2f; } void UpdateTail() { if (tailSystem == null) return; var emission = tailSystem.emission; if (thermosphereLevel >= 1f) { emission.rateOverTime = 0f; return; } float t = Mathf.InverseLerp(1f, 0f, thermosphereLevel); emission.rateOverTime = Mathf.Lerp(0f, 500f, t); var main = tailSystem.main; main.startSpeed = new ParticleSystem.MinMaxCurve( Mathf.Lerp(3f, 15f, t), Mathf.Lerp(8f, 30f, t) ); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.6f, 0.8f, 1f, Mathf.Lerp(0.1f, 0.6f, t)), new Color(0.4f, 0.6f, 1f, Mathf.Lerp(0.05f, 0.3f, t)) ); } void UpdateSolarWind() { if (solarWindSystem == null) return; var emission = solarWindSystem.emission; if (thermosphereLevel >= 1f) { emission.rateOverTime = 0f; return; } float t = Mathf.InverseLerp(1f, 0f, thermosphereLevel); emission.rateOverTime = Mathf.Lerp(0f, 800f, t); var main = solarWindSystem.main; main.startColor = new ParticleSystem.MinMaxGradient( new Color(1f, 0.7f, 0.1f, Mathf.Lerp(0.3f, 1f, t)), new Color(1f, 0.5f, 0.0f, Mathf.Lerp(0.2f, 0.8f, t)) ); } void UpdateAurora() { if (auroraSystem == null) return; var emission = auroraSystem.emission; if (thermosphereLevel >= 0.7f) { emission.rateOverTime = Mathf.Lerp(0f, 20f, Mathf.InverseLerp(1f, 0.7f, thermosphereLevel)); } else if (thermosphereLevel >= 0.3f) { emission.rateOverTime = Mathf.Lerp(20f, 60f, Mathf.InverseLerp(0.7f, 0.3f, thermosphereLevel)); } else { emission.rateOverTime = 0f; if (auroraGlow != null) auroraGlow.GetComponent().intensity = 0f; return; } if (auroraGlow != null) auroraGlow.GetComponent().intensity = Mathf.Lerp(0f, 0.5f, Mathf.InverseLerp(1f, 0.3f, thermosphereLevel)); } public void CleanUp() { if (tailSystem != null) Destroy(tailSystem.gameObject); if (solarWindSystem != null) Destroy(solarWindSystem.gameObject); if (auroraSystem != null) Destroy(auroraSystem.gameObject); if (auroraGlow != null) Destroy(auroraGlow); tailSystem = null; solarWindSystem = null; auroraSystem = null; auroraGlow = null; enabled = false; } }