Skip to content

Instantly share code, notes, and snippets.

@ginomessmer
Last active March 13, 2023 17:51
Show Gist options
  • Save ginomessmer/c160fb0591271d5818674fad466db40c to your computer and use it in GitHub Desktop.
Save ginomessmer/c160fb0591271d5818674fad466db40c to your computer and use it in GitHub Desktop.
Extended Day/Night Cycle for Unity 5
using System;
using UnityEngine;
[RequireComponent(typeof(Light))]
public class TimeCycle : MonoBehaviour
{
public float CurrentTimeOfDay = 0;
public DayTime CurrentDayTime;
public float Hour = 0;
public float Minute = 0;
[HideInInspector()]
public System.DateTime CurrentDate = DateTime.Now;
public float SecondsInFullDay = 120f;
public float TimeMultiplier = 5f;
public float Angle = 150;
public Gradient NightDayGradient;
public float MaxIntensity = 3f;
public float MinIntensity = 0f;
public float MinPoint = -0.2f;
public float ReflectionMax = 0.5f;
public float MaxAmbient = 1f;
public float MinAmbient = 0f;
public float MinAmbientPoint = -0.2f;
public Gradient NightDayFogGradient;
public AnimationCurve FogDensityCurve;
public float FogScale = 1f;
public float DayAtmosphereThickness = 0.4f;
public float NightAtmosphereThickness = 0.87f;
Light mainLight;
Material skyMaterial;
public string NightLightTagName = "DynamicCycleLight";
public bool DisableSunShadowAtNight = true;
private bool areLightsOn = false;
// Use this for initialization
void Start()
{
mainLight = GetComponent<Light>();
skyMaterial = RenderSettings.skybox;
}
// Update is called once per frame
void Update()
{
UpdateLightning();
RotateSun();
CalculateDateTime();
EvaluateCycleActions();
}
private void UpdateLightning()
{
float tRange = 1 - MinPoint;
float dot = Mathf.Clamp01((Vector3.Dot(mainLight.transform.forward, Vector3.down) - MinPoint) / tRange);
float i = ((MaxIntensity - MinIntensity) * dot) + MinIntensity;
mainLight.intensity = i;
tRange = 1 - MinAmbientPoint;
dot = Mathf.Clamp01((Vector3.Dot(mainLight.transform.forward, Vector3.down) - MinAmbientPoint) / tRange);
i = ((MaxAmbient - MinAmbientPoint) * dot) + MinAmbient;
RenderSettings.ambientIntensity = i;
mainLight.color = NightDayGradient.Evaluate(dot);
RenderSettings.ambientLight = mainLight.color;
RenderSettings.reflectionIntensity = Mathf.Clamp(i, 0, ReflectionMax); //
RenderSettings.fogColor = NightDayFogGradient.Evaluate(dot);
RenderSettings.fogDensity = FogDensityCurve.Evaluate(dot) * FogScale;
i = ((DayAtmosphereThickness - NightAtmosphereThickness) * dot) + NightAtmosphereThickness;
skyMaterial.SetFloat("_AtmosphereThickness", i);
}
private void RotateSun()
{
CurrentTimeOfDay += (Time.deltaTime / SecondsInFullDay) * TimeMultiplier;
if (CurrentTimeOfDay >= 1)
CurrentTimeOfDay = 0;
this.transform.localRotation = Quaternion.Euler((CurrentTimeOfDay * 360f) - 90, Angle, 0);
}
private void CalculateDateTime()
{
// Calculate hours and minutes
this.Hour = 24 * CurrentTimeOfDay;
this.Minute = 60 * (Hour - Mathf.Floor(Hour));
}
public void EvaluateCycleActions()
{
// Evaluate day time
switch ((int)(CurrentTimeOfDay * 100))
{
case 0:
this.CurrentDayTime = DayTime.Midnight;
break;
case 25:
this.CurrentDayTime = DayTime.Sunrise;
break;
case 50:
this.CurrentDayTime = DayTime.Noon;
break;
case 75:
this.CurrentDayTime = DayTime.Sunset;
break;
}
// Do some actions
if (this.CurrentDayTime == DayTime.Sunset || this.CurrentDayTime == DayTime.Midnight)
{
this.TurnDynamicLights(true);
this.GetComponent<Light>().shadowStrength = this.DisableSunShadowAtNight == false ? 1 : 0;
}
else if (this.CurrentDayTime == DayTime.Sunrise || this.CurrentDayTime == DayTime.Noon)
{
this.TurnDynamicLights(false);
this.GetComponent<Light>().shadowStrength = 1;
}
}
private void TurnDynamicLights(bool on)
{
if (areLightsOn == on)
return; // Skip, don't need to call
Debug.Log("Turning lights to " + on);
foreach (var light in GameObject.FindGameObjectsWithTag(NightLightTagName))
{
light.GetComponent<Light>().enabled = on;
}
areLightsOn = on;
}
public enum DayTime
{
Midnight,
Sunrise,
Noon,
Sunset
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment