using System; using UnityEngine; public class TimeManager : MonoBehaviour { public static Action OnMinuteChanged; [SerializeField] private float _startHour; [SerializeField] private Light _sunLight; [SerializeField] private float _sunriseHour; [SerializeField] private float _sunsetHour; [SerializeField] private Color _dayAmbientLight; [SerializeField] private Color _nightAmbientLight; [SerializeField] private AnimationCurve _lightChangeCurve; [SerializeField] private float _maxSunLightIntensity; [SerializeField] private Light _moonLight; [SerializeField] private float _maxMoonLightIntensity; private TimeSpan _sunriseTime; private TimeSpan _sunsetTime; private float _timer; [SerializeField] private float _minuteToRealTime = 0.05f; private static TimeSpan _currentTime; public static TimeSpan CurrentTime => _currentTime; // Start is called before the first frame update void Start() { _timer = _minuteToRealTime; _currentTime = TimeSpan.Zero + TimeSpan.FromHours(_startHour); _sunriseTime = TimeSpan.FromHours(_sunriseHour); _sunsetTime = TimeSpan.FromHours(_sunsetHour); } // Update is called once per frame void Update() { UpdateTime(); RotateSun(); } private void UpdateTime() { _timer -= Time.deltaTime; if (_timer <= 0) { _currentTime = _currentTime.Add(TimeSpan.FromMinutes(1)); OnMinuteChanged?.Invoke(); _timer = _minuteToRealTime; } } private void RotateSun() { float sunLightRotation; if (_currentTime > _sunriseTime && _currentTime < _sunsetTime) { TimeSpan sunriseToSunsetDuration = CalculateTimeDifference(_sunriseTime, _sunsetTime); TimeSpan timeSinceSunrise = CalculateTimeDifference(_sunriseTime, _currentTime); double percentage = timeSinceSunrise.TotalMinutes / sunriseToSunsetDuration.TotalMinutes; sunLightRotation = Mathf.Lerp(0, 180, (float)percentage); } else { TimeSpan nightDuration = CalculateTimeDifference(_sunsetTime, _sunriseTime); TimeSpan timeSinceSunset = CalculateTimeDifference(_sunsetTime, _currentTime); double percentage = timeSinceSunset.TotalMinutes / nightDuration.TotalMinutes; sunLightRotation = Mathf.Lerp(180, 360, (float)percentage); } _sunLight.transform.rotation = Quaternion.AngleAxis(sunLightRotation, Vector3.right); } private void UpdateLightSettings() { float dotProduct = Vector3.Dot(_sunLight.transform.forward, Vector3.down); _sunLight.intensity = Mathf.Lerp(0, _maxSunLightIntensity, _lightChangeCurve.Evaluate(dotProduct)); _moonLight.intensity = Mathf.Lerp(_maxMoonLightIntensity, 0, _lightChangeCurve.Evaluate(dotProduct)); RenderSettings.ambientLight = Color.Lerp(_nightAmbientLight, _dayAmbientLight, _lightChangeCurve.Evaluate(dotProduct)); } private TimeSpan CalculateTimeDifference(TimeSpan from, TimeSpan to) { TimeSpan diff = to - from; if (diff.TotalSeconds < 0) { diff += TimeSpan.FromHours(24); } return diff; } }