Last active
March 13, 2023 17:51
-
-
Save ginomessmer/c160fb0591271d5818674fad466db40c to your computer and use it in GitHub Desktop.
Extended Day/Night Cycle for Unity 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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