using System.Collections; using System.Collections.Generic; using UnityEngine; public class MarsEffects : MonoBehaviour { [Header("Οθλ")] public Material dustMaterial; public float planetRadius = 6.779f; [Range(0f, 1f)] public float troposphereLevel = 1f; public float previousLevel = 1f; private List dustClusters = new List(); private Light nightLight; private bool initialized = false; private const int DUST_COUNT = 20; void Awake() { enabled = false; } public void InitState() { foreach (var ps in dustClusters) if (ps != null) Destroy(ps.gameObject); dustClusters.Clear(); if (nightLight != null) { Destroy(nightLight.gameObject); nightLight = null; } troposphereLevel = 1f; previousLevel = 1f; initialized = false; CreateDustSystem(); CreateNightLight(); initialized = true; } void CreateDustSystem() { for (int i = 0; i < DUST_COUNT; i++) { Vector3 dir = Random.onUnitSphere; Vector3 pos = transform.position + dir * (planetRadius + Random.Range(0.5f, 2f)); GameObject obj = new GameObject("DustCluster_" + i); obj.transform.parent = null; obj.transform.position = pos; ParticleSystem ps = obj.AddComponent(); var main = ps.main; main.loop = true; main.playOnAwake = true; main.maxParticles = 200; main.startLifetime = new ParticleSystem.MinMaxCurve(5f, 12f); main.startSpeed = new ParticleSystem.MinMaxCurve(0f, 0.5f); main.startSize = new ParticleSystem.MinMaxCurve(0.1f, 0.4f); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.9f, 0.5f, 0.2f, 0.5f), new Color(0.7f, 0.35f, 0.1f, 0.3f) ); main.simulationSpace = ParticleSystemSimulationSpace.World; main.gravityModifier = 0f; var emission = ps.emission; emission.rateOverTime = 20f; var shape = ps.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Sphere; shape.radius = 1.5f; shape.radiusThickness = 1f; var colorOverLifetime = ps.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(0.9f, 0.5f, 0.2f), 0f), new GradientColorKey(new Color(0.7f, 0.35f, 0.1f), 0.5f), new GradientColorKey(new Color(0.5f, 0.25f, 0.08f), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(0.5f, 0.2f), new GradientAlphaKey(0.3f, 0.7f), new GradientAlphaKey(0f, 1f) } ); colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient); var noise = ps.noise; noise.enabled = true; noise.strength = 0.8f; noise.frequency = 0.3f; noise.scrollSpeed = 0.2f; noise.octaveCount = 2; var renderer = ps.GetComponent(); renderer.renderMode = ParticleSystemRenderMode.Billboard; renderer.sortingFudge = 3f; if (dustMaterial != null) renderer.material = dustMaterial; ps.Play(); dustClusters.Add(ps); StartCoroutine(OrbitDust(obj.transform, dir, planetRadius + Random.Range(0.5f, 2f))); } } void CreateNightLight() { GameObject lightObj = new GameObject("MarsNightLight"); lightObj.transform.parent = null; lightObj.transform.position = transform.position + Vector3.right * (planetRadius * 3f); nightLight = lightObj.AddComponent(); nightLight.type = LightType.Spot; nightLight.color = new Color(0.8f, 0.3f, 0.1f); nightLight.intensity = 0f; nightLight.range = planetRadius * 400f; nightLight.spotAngle = 170f; nightLight.shadows = LightShadows.None; StartCoroutine(OrbitLight(lightObj.transform)); } IEnumerator OrbitDust(Transform dust, Vector3 axis, float radius) { Vector3 orbitAxis = Vector3.Cross(axis, Random.onUnitSphere).normalized; float speed = Random.Range(1f, 4f); float wobbleSpeed = Random.Range(0.1f, 0.3f); float wobbleAmount = Random.Range(0.1f, 0.3f); while (dust != null) { dust.RotateAround(transform.position, orbitAxis, speed * Time.deltaTime); float wobble = Mathf.Sin(Time.time * wobbleSpeed) * wobbleAmount; dust.position = transform.position + (dust.position - transform.position).normalized * (radius + wobble); yield return null; } } void UpdateDust() { float level = troposphereLevel; foreach (var ps in dustClusters) { if (ps == null) continue; var emission = ps.emission; var main = ps.main; if (level >= 0.7f) { float t = Mathf.InverseLerp(1f, 0.7f, level); emission.rateOverTime = Mathf.Lerp(20f, 12f, t); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.9f, 0.5f, 0.2f, Mathf.Lerp(0.5f, 0.35f, t)), new Color(0.7f, 0.35f, 0.1f, Mathf.Lerp(0.3f, 0.2f, t)) ); } else if (level >= 0.5f) { float t = Mathf.InverseLerp(0.7f, 0.5f, level); emission.rateOverTime = Mathf.Lerp(12f, 5f, t); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.9f, 0.5f, 0.2f, Mathf.Lerp(0.35f, 0.15f, t)), new Color(0.7f, 0.35f, 0.1f, Mathf.Lerp(0.2f, 0.08f, t)) ); } else if (level >= 0.3f) { float t = Mathf.InverseLerp(0.5f, 0.3f, level); emission.rateOverTime = Mathf.Lerp(5f, 1f, t); main.startColor = new ParticleSystem.MinMaxGradient( new Color(0.9f, 0.5f, 0.2f, Mathf.Lerp(0.15f, 0.03f, t)), new Color(0.7f, 0.35f, 0.1f, Mathf.Lerp(0.08f, 0.01f, t)) ); } else { emission.rateOverTime = 0f; } } } void UpdateNightLight() { if (nightLight == null) return; if (troposphereLevel >= 1f) nightLight.intensity = 0f; else if (troposphereLevel >= 0.7f) nightLight.intensity = Mathf.Lerp(200f, 400f, Mathf.InverseLerp(1f, 0.7f, troposphereLevel)); else if (troposphereLevel >= 0.5f) nightLight.intensity = Mathf.Lerp(400f, 450f, Mathf.InverseLerp(0.7f, 0.5f, troposphereLevel)); else if (troposphereLevel >= 0.3f) nightLight.intensity = Mathf.Lerp(450f, 500f, Mathf.InverseLerp(0.5f, 0.3f, troposphereLevel)); else nightLight.intensity = Mathf.Lerp(500f, 600f, Mathf.InverseLerp(0.3f, 0f, troposphereLevel)); } IEnumerator OrbitLight(Transform lightTransform) { float angle = 0f; float speed = 60f; while (lightTransform != null && nightLight != null) { angle += speed * Time.deltaTime; float rad = angle * Mathf.Deg2Rad; lightTransform.position = transform.position + new Vector3(Mathf.Cos(rad), 0.3f, Mathf.Sin(rad)) * (planetRadius * 3f); lightTransform.LookAt(transform.position); nightLight.range = planetRadius * 400f; nightLight.spotAngle = 170f; yield return null; } } void Update() { if (!Application.isPlaying) return; if (troposphereLevel >= 1f && previousLevel < 1f) InitState(); previousLevel = troposphereLevel; UpdateDust(); UpdateNightLight(); } public void CleanUp() { foreach (var ps in dustClusters) if (ps != null) Destroy(ps.gameObject); dustClusters.Clear(); if (nightLight != null) { Destroy(nightLight.gameObject); nightLight = null; } enabled = false; } }