using UnityEngine; namespace UnityAgent { /// /// Rotates a directional light around the world to simulate a day/night /// cycle. Also lerps between day and night sky/ambient colors and turns /// street lights on after sunset. /// public class DayNightCycle : MonoBehaviour { [Header("Sun")] public Light sun; public float dayLengthSeconds = 120f; [Header("Colors")] public Color daySky = new Color(0.5f, 0.7f, 1.0f); public Color nightSky = new Color(0.03f, 0.04f, 0.08f); public Color dayAmbient = new Color(0.6f, 0.6f, 0.6f); public Color nightAmbient = new Color(0.12f, 0.13f, 0.18f); [Header("Lights")] public Light[] streetLights; public float streetLightThreshold = 0.2f; private float _timeOfDay; // 0..1 private void Start() { if (sun == null) sun = GetComponent(); RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat; } private void Update() { _timeOfDay = (_timeOfDay + Time.deltaTime / dayLengthSeconds) % 1f; // Sun angle: at timeOfDay=0.25 sun is at noon. float sunAngle = (_timeOfDay - 0.25f) * 360f; if (sun != null) { sun.transform.rotation = Quaternion.Euler(sunAngle, -30f, 0f); float dayFactor = Mathf.Clamp01(Mathf.Cos((_timeOfDay - 0.25f) * Mathf.PI * 2f) * 0.5f + 0.5f); sun.intensity = dayFactor * 1.2f; } float t = Mathf.Clamp01(Mathf.Cos((_timeOfDay - 0.25f) * Mathf.PI * 2f) * 0.5f + 0.5f); RenderSettings.ambientLight = Color.Lerp(nightAmbient, dayAmbient, t); Camera mainCam = Camera.main; if (mainCam != null) { mainCam.backgroundColor = Color.Lerp(nightSky, daySky, t); } UpdateStreetLights(t); } private void UpdateStreetLights(float dayFactor) { if (streetLights == null) return; bool on = dayFactor < streetLightThreshold; foreach (var l in streetLights) if (l != null) l.enabled = on; } /// Current time of day in 0..1 range (0=midnight). public float TimeOfDay => _timeOfDay; } }