using System.Collections; using System.Collections.Generic; using UnityEngine; public class JupiterTroposphereEffects : MonoBehaviour { [Header("Налаштування")] public Material stormMaterial; public Material ringMaterial; public Material redSpotMaterial; public float planetRadius = 72f; [Range(0f, 1f)] public float troposphereLevel = 1f; public float previousLevel = 1f; private List bandClusters = new List(); private ParticleSystem ringSystem; private ParticleSystem redSpotSystem; private Light redSpotGlow; void Awake() { enabled = false; } public void InitState() { foreach (var ps in bandClusters) if (ps != null) Destroy(ps.gameObject); bandClusters.Clear(); if (ringSystem != null) Destroy(ringSystem.gameObject); if (redSpotSystem != null) Destroy(redSpotSystem.gameObject); if (redSpotGlow != null) Destroy(redSpotGlow.gameObject); ringSystem = null; redSpotSystem = null; redSpotGlow = null; troposphereLevel = 1f; previousLevel = 1f; CreateBands(); CreateRing(); CreateRedSpot(); } void CreateBands() { float[] latitudes = { -55f, -25f, -8f, 8f, 25f, 55f }; float[] speeds = { 4f, -3f, 5f, -5f, 3f, -4f }; Color[] colors = { new Color(0.7f, 0.45f, 0.2f), new Color(0.85f, 0.6f, 0.3f), new Color(0.75f, 0.5f, 0.22f), new Color(0.8f, 0.55f, 0.25f), new Color(0.72f, 0.48f, 0.2f), new Color(0.68f, 0.42f, 0.18f) }; for (int i = 0; i < latitudes.Length; i++) { GameObject obj = new GameObject("JupiterBand_" + i); obj.transform.parent = null; obj.transform.position = transform.position; ParticleSystem ps = obj.AddComponent(); var main = ps.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 2000; main.startLifetime = new ParticleSystem.MinMaxCurve(5f, 10f); main.startSpeed = new ParticleSystem.MinMaxCurve(0f, 0f); main.startSize = new ParticleSystem.MinMaxCurve(1f, 3f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(colors[i].r, colors[i].g, colors[i].b, 0.4f), new Color(colors[i].r * 0.8f, colors[i].g * 0.8f, colors[i].b * 0.8f, 0.2f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = ps.emission; emission.rateOverTime = 0f; var shape = ps.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Sphere; shape.radius = planetRadius; shape.radiusThickness = 0.02f; shape.arc = 360f; shape.rotation = new Vector3(latitudes[i], 0f, 0f); var vel = ps.velocityOverLifetime; vel.enabled = true; vel.space = ParticleSystemSimulationSpace.World; vel.orbitalX = new ParticleSystem.MinMaxCurve(0f); vel.orbitalY = new ParticleSystem.MinMaxCurve(speeds[i]); vel.orbitalZ = new ParticleSystem.MinMaxCurve(0f); vel.x = new ParticleSystem.MinMaxCurve(0f); vel.y = new ParticleSystem.MinMaxCurve(0f); vel.z = new ParticleSystem.MinMaxCurve(0f); var colorOverLifetime = ps.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(colors[i], 0f), new GradientColorKey(colors[i] * 0.8f, 0.5f), new GradientColorKey(colors[i] * 0.6f, 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(0.4f, 0.15f), new GradientAlphaKey(0.3f, 0.8f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var noise = ps.noise; noise.enabled = true; noise.strength = 0.5f; noise.frequency = 0.2f; noise.scrollSpeed = 0.1f; var renderer = ps.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Billboard; renderer.sortingFudge = 4f; if (stormMaterial != null) renderer.material = stormMaterial; ps.Play(); bandClusters.Add(ps); } } void CreateRing() { float ringRadius = planetRadius * 1.8f; GameObject obj = new GameObject("JupiterRing"); obj.transform.parent = null; obj.transform.position = transform.position; obj.transform.rotation = Quaternion.Euler(90f, 0f, 0f); ringSystem = obj.AddComponent(); var main = ringSystem.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 5000; main.startLifetime = new ParticleSystem.MinMaxCurve(6f, 12f); main.startSpeed = new ParticleSystem.MinMaxCurve(0f, 0f); main.startSize = new ParticleSystem.MinMaxCurve(0.2f, 0.5f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.35f, 0.28f, 0.2f, 0.35f), new Color(0.28f, 0.22f, 0.15f, 0.2f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = ringSystem.emission; emission.rateOverTime = 150f; var shape = ringSystem.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Donut; shape.radius = ringRadius; shape.donutRadius = 1.5f; shape.radiusThickness = 1f; shape.arc = 360f; shape.rotation = new Vector3(0f, 0f, 0f); var vel = ringSystem.velocityOverLifetime; vel.enabled = true; vel.space = ParticleSystemSimulationSpace.World; vel.orbitalX = new ParticleSystem.MinMaxCurve(0f); vel.orbitalY = new ParticleSystem.MinMaxCurve(2f); vel.orbitalZ = new ParticleSystem.MinMaxCurve(0f); vel.x = new ParticleSystem.MinMaxCurve(0f); vel.y = new ParticleSystem.MinMaxCurve(0f); vel.z = new ParticleSystem.MinMaxCurve(0f); var colorOverLifetime = ringSystem.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(0.4f, 0.32f, 0.22f), 0f), new GradientColorKey(new Color(0.35f, 0.27f, 0.18f), 0.5f), new GradientColorKey(new Color(0.28f, 0.22f, 0.15f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(0.35f, 0.1f), new GradientAlphaKey(0.25f, 0.8f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var renderer = ringSystem.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Billboard; renderer.sortingFudge = 3f; if (ringMaterial != null) renderer.material = ringMaterial; else if (stormMaterial != null) renderer.material = stormMaterial; ringSystem.Play(); } void CreateRedSpot() { Vector3 redSpotDir = new Vector3(0.2f, -0.15f, 0.97f).normalized; Vector3 redSpotPos = transform.position + redSpotDir * (planetRadius * 1.02f); GameObject obj = new GameObject("JupiterRedSpot"); obj.transform.parent = null; obj.transform.position = transform.position; obj.transform.up = Vector3.up; redSpotSystem = obj.AddComponent(); var main = redSpotSystem.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 3000; main.startLifetime = new ParticleSystem.MinMaxCurve(3f, 6f); main.startSpeed = new ParticleSystem.MinMaxCurve(0f, 0f); main.startSize = new ParticleSystem.MinMaxCurve(2f, 5f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.95f, 0.15f, 0.05f, 0.9f), new Color(0.8f, 0.1f, 0.02f, 0.6f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = redSpotSystem.emission; emission.rateOverTime = 200f; var shape = redSpotSystem.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Sphere; shape.radius = planetRadius * 0.12f; shape.radiusThickness = 1f; shape.position = redSpotDir * (planetRadius * 1.02f); var vel = redSpotSystem.velocityOverLifetime; vel.enabled = true; vel.space = ParticleSystemSimulationSpace.World; vel.orbitalX = new ParticleSystem.MinMaxCurve(0f); vel.orbitalY = new ParticleSystem.MinMaxCurve(-6f); vel.orbitalZ = new ParticleSystem.MinMaxCurve(0f); vel.x = new ParticleSystem.MinMaxCurve(0f); vel.y = new ParticleSystem.MinMaxCurve(0f); vel.z = new ParticleSystem.MinMaxCurve(0f); var colorOverLifetime = redSpotSystem.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(0.95f, 0.15f, 0.05f), 0f), new GradientColorKey(new Color(0.8f, 0.1f, 0.02f), 0.4f), new GradientColorKey(new Color(0.6f, 0.08f, 0.01f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0.6f, 0.5f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var noise = redSpotSystem.noise; noise.enabled = true; noise.strength = 0.8f; noise.frequency = 0.3f; noise.scrollSpeed = 0.2f; noise.octaveCount = 2; var renderer = redSpotSystem.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Billboard; renderer.sortingFudge = 5f; if (redSpotMaterial != null) renderer.material = redSpotMaterial; else if (stormMaterial != null) renderer.material = stormMaterial; redSpotSystem.Play(); GameObject glowObj = new GameObject("RedSpotGlow"); glowObj.transform.parent = null; glowObj.transform.position = redSpotPos; redSpotGlow = glowObj.AddComponent(); redSpotGlow.type = LightType.Point; redSpotGlow.color = new Color(0.95f, 0.15f, 0.05f); redSpotGlow.intensity = 5f; redSpotGlow.range = planetRadius * 6f; } void UpdateRedSpot() { if (redSpotSystem == null) return; var redEmission = redSpotSystem.emission; float t = Mathf.InverseLerp(1f, 0f, troposphereLevel); redEmission.rateOverTime = Mathf.Lerp(200f, 0f, t); if (redSpotGlow != null) redSpotGlow.intensity = Mathf.Lerp(5f, 0f, t); } public void CleanUp() { foreach (var ps in bandClusters) if (ps != null) Destroy(ps.gameObject); bandClusters.Clear(); if (ringSystem != null) Destroy(ringSystem.gameObject); if (redSpotSystem != null) Destroy(redSpotSystem.gameObject); if (redSpotGlow != null) Destroy(redSpotGlow.gameObject); ringSystem = null; redSpotSystem = null; redSpotGlow = null; enabled = false; } void UpdateBands() { foreach (var ps in bandClusters) { if (ps == null) continue; var emission = ps.emission; if (troposphereLevel >= 0.7f) emission.rateOverTime = 0f; else if (troposphereLevel >= 0.5f) emission.rateOverTime = Mathf.Lerp(0f, 50f, Mathf.InverseLerp(0.7f, 0.5f, troposphereLevel)); else if (troposphereLevel >= 0.3f) emission.rateOverTime = Mathf.Lerp(50f, 150f, Mathf.InverseLerp(0.5f, 0.3f, troposphereLevel)); else emission.rateOverTime = Mathf.Lerp(150f, 300f, Mathf.InverseLerp(0.3f, 0f, troposphereLevel)); } } void Update() { if (!Application.isPlaying) return; if (troposphereLevel >= 1f && previousLevel < 1f) InitState(); previousLevel = troposphereLevel; UpdateBands(); UpdateRedSpot(); } }