riversong code showcase
This commit is contained in:
133
Source/Riversong/Game/World/Time/DayNightCycleLightingSystem.cs
Normal file
133
Source/Riversong/Game/World/Time/DayNightCycleLightingSystem.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
[RequiresWorldReadyForUpdate]
|
||||
[GameSystemGroup(typeof(LateGameSystemGroup))]
|
||||
[UpdateAfter(typeof(WorldTimeSystem))]
|
||||
public class DayNightCycleLightingSystem : GameSystem, IInitializable, IDisposable, IUpdatable
|
||||
{
|
||||
[InjectService]
|
||||
private GameConfig _config;
|
||||
|
||||
[InjectService]
|
||||
private IScene _scene;
|
||||
|
||||
[InjectService]
|
||||
private World _world;
|
||||
|
||||
private Quaternion _initialLightRotation;
|
||||
|
||||
public DayNightCycleLightingSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
||||
{
|
||||
}
|
||||
|
||||
public UniTask InitializeAsync()
|
||||
{
|
||||
_initialLightRotation = _scene.MainLight.transform.localRotation;
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Shader.SetGlobalFloat(ShaderProperties.NightBlend, 0);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
var nightBlend = _world.TimeState.NightBlend;
|
||||
Shader.SetGlobalFloat(ShaderProperties.NightBlend, nightBlend);
|
||||
|
||||
UpdateLightRig(nightBlend);
|
||||
UpdateShadows(nightBlend);
|
||||
UpdateAmbientLighting(nightBlend);
|
||||
UpdatePostProcessing(nightBlend);
|
||||
}
|
||||
|
||||
private void UpdateLightRig(float nightBlend)
|
||||
{
|
||||
_scene.LightRig.transform.localRotation = _world.TimeState.DayNightCycleStep switch
|
||||
{
|
||||
DayNightCycleStep.Day => Quaternion.identity,
|
||||
DayNightCycleStep.DayToNight => Quaternion.Euler(0, nightBlend * 360, 0),
|
||||
DayNightCycleStep.Night => Quaternion.identity,
|
||||
DayNightCycleStep.NightToDay => Quaternion.Euler(0, -nightBlend * 360, 0),
|
||||
_ => throw new ArgumentException()
|
||||
};
|
||||
|
||||
var dayRotation = _initialLightRotation;
|
||||
var nightRotation = _initialLightRotation * Quaternion.Euler(-90, 0, 0);
|
||||
|
||||
_scene.MainLight.transform.localRotation = _world.TimeState.DayNightCycleStep switch
|
||||
{
|
||||
DayNightCycleStep.Day => dayRotation,
|
||||
DayNightCycleStep.DayToNight => Quaternion.Slerp(dayRotation, nightRotation, nightBlend),
|
||||
DayNightCycleStep.Night => nightRotation,
|
||||
DayNightCycleStep.NightToDay => Quaternion.Slerp(nightRotation, dayRotation, 1 - nightBlend),
|
||||
_ => throw new ArgumentException()
|
||||
};
|
||||
|
||||
_scene.NightLight.transform.localRotation = _world.TimeState.DayNightCycleStep switch
|
||||
{
|
||||
DayNightCycleStep.Day => nightRotation,
|
||||
DayNightCycleStep.DayToNight => Quaternion.Slerp(nightRotation, dayRotation, nightBlend),
|
||||
DayNightCycleStep.Night => dayRotation,
|
||||
DayNightCycleStep.NightToDay => Quaternion.Slerp(dayRotation, nightRotation, 1 - nightBlend),
|
||||
_ => throw new ArgumentException()
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateShadows(float nightBlend)
|
||||
{
|
||||
const float fadeSpeed = 2;
|
||||
|
||||
var mainLightT = Mathf.Clamp01(fadeSpeed * nightBlend);
|
||||
UpdateShadows(_scene.MainLight, Mathf.Lerp(_config.Time.DayLighting.ShadowStrength, 0, mainLightT));
|
||||
|
||||
var nightLightT = Mathf.Clamp01(fadeSpeed * (1 - nightBlend));
|
||||
UpdateShadows(_scene.NightLight, Mathf.Lerp(_config.Time.NightLighting.ShadowStrength, 0, nightLightT));
|
||||
}
|
||||
|
||||
private static void UpdateShadows(Light light, float shadowStrength)
|
||||
{
|
||||
light.shadowStrength = shadowStrength;
|
||||
light.shadows = shadowStrength > 0 ? LightShadows.Soft : LightShadows.None;
|
||||
}
|
||||
|
||||
private void UpdateAmbientLighting(float nightBlend)
|
||||
{
|
||||
RenderSettings.ambientLight = Color.Lerp(_config.Time.DayLighting.AmbientColor, _config.Time.NightLighting.AmbientColor, nightBlend);
|
||||
}
|
||||
|
||||
private void UpdatePostProcessing(float nightBlend)
|
||||
{
|
||||
_scene.NightVolume.weight = nightBlend;
|
||||
_scene.BloomVolume.weight = nightBlend;
|
||||
_scene.WarmTintVolume.weight = GetWarmTintBlend();
|
||||
}
|
||||
|
||||
private float GetWarmTintBlend()
|
||||
{
|
||||
var step = _world.TimeState.DayNightCycleStep;
|
||||
if (step != DayNightCycleStep.DayToNight && step != DayNightCycleStep.NightToDay) return 0;
|
||||
|
||||
var config = _config.Time;
|
||||
|
||||
var time = _world.TimeState.DayNightCycleTime;
|
||||
var blend = step == DayNightCycleStep.DayToNight ? Mathf.Clamp01(time / config.DayToNightDuration) : Mathf.Clamp01(time / config.NightToDayDuration);
|
||||
|
||||
var rampUp = config.WarmTintRampUp;
|
||||
var rampDown = config.WarmTintRampDown;
|
||||
|
||||
if (blend <= rampUp.x) return 0;
|
||||
if (blend < rampUp.y) return Mathf.SmoothStep(0, 1, Mathf.InverseLerp(rampUp.x, rampUp.y, blend));
|
||||
if (blend <= rampDown.x) return 1;
|
||||
if (blend < rampDown.y) return Mathf.SmoothStep(1, 0, Mathf.InverseLerp(rampDown.x, rampDown.y, blend));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user