Just wanted to share a simple script to control sun rotation, it allows to realistically rotate light direction taking into account time of day, position on the earth or season.

North is assumed to be towards Z axis, but can be changed with horizonRotation.
Time is normalized and starts from midnight, earthTilt is tilt of the planet and starts from summer solstice (zero will be equinox), and the last parameter is geographical latitude (zero is equator).
using UnityEngine;
namespace Game.Rendering.Lighting
{
[ExecuteAlways]
public class LightingController : MonoBehaviour
{
public const float Time2DayTime = 24f;
[SerializeField] private Light sun;
[SerializeField, Range(0f, 360f)] private float horizonRotation = 0f;
[Header("Settings")]
[Tooltip("Normalized time of day. Zero equals to midnight, 0.5 equals to noon.")]
[SerializeField, Range(0f, 1f)] private float time = 14f/24f;
[Tooltip("Tilt of planet from June 22 to December 22.")]
[SerializeField, Range(-23.5f, 23.5f)] private float earthTilt = -23.5f;
[Tooltip("Location latitude. Zero is equator.")]
[SerializeField, Range(-90f, 90f)] private float latitude = 50f;
public float TimeOfDay => time * Time2DayTime;
private void Reset()
{
sun = GetComponent<Light>();
}
private void Update()
{
if (sun == null)
{
return;
}
Vector3 sunDirection = CalculateSunDirection(time, latitude, earthTilt, horizonRotation);
sun.transform.rotation = Quaternion.LookRotation(-sunDirection);
}
public static Vector3 CalculateSunDirection(float normalizedTimeOfDay, float latitude, float planetTilt, float horizonRotation = 0f)
{
return Quaternion.Euler(0, horizonRotation, 0) * Quaternion.Euler(90f - latitude, 0, 0) * Quaternion.Euler(0, normalizedTimeOfDay * 360f, 0) * Quaternion.Euler(planetTilt, 0, 0) * Vector3.forward;
}
private void OnDrawGizmosSelected()
{
float orbitRadius = 30f;
int orbitSegments = 24;
float sunSize = 5f;
// Orbit
Gizmos.color = new Color(1f, 1f, 0.6f);
for (int i = 0; i < orbitSegments; i++)
{
Vector3 nextSegmentDirection = CalculateSunDirection((float)((i + 1) % orbitSegments) / orbitSegments, latitude, earthTilt, horizonRotation);
Vector3 segmentDirection = CalculateSunDirection((float)i / orbitSegments, latitude, earthTilt, horizonRotation);
Gizmos.DrawLine(transform.position + segmentDirection * orbitRadius, transform.position + nextSegmentDirection * orbitRadius);
}
// Sun
if (sun != null)
{
Gizmos.color = sun.color;
}
Vector3 sunDirection = CalculateSunDirection(time, latitude, earthTilt, horizonRotation);
Gizmos.DrawSphere(transform.position + sunDirection * orbitRadius, sunSize);
}
}
}
There is also additional gizmo
