using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering.HighDefinition; [ExecuteAlways] public class CelestialBodiesManager : MonoBehaviour { [Serializable] public class CelestialBodyData { public Light light; public HDAdditionalLightData hdLightData; public Transform transform; public float evaluatedIntensity; public float fadeFactor; public float shadowFadeFactor; public bool shadowEnabled; public float volumetricMultiplier = 1f; public CelestialBodyData(Light _light) { if (_light != null) { light = _light; transform = light.transform; hdLightData = light.GetComponent(); evaluatedIntensity = light.intensity; } else { light = null; transform = null; hdLightData = null; evaluatedIntensity = 1f; } fadeFactor = 1f; shadowFadeFactor = 1f; shadowEnabled = false; } public float Evaluate(float fadeStart, float fadeEnd) { float x = transform.eulerAngles.x; fadeFactor = GetHorizonMultiplier(x, fadeStart, fadeEnd); shadowFadeFactor = fadeFactor; evaluatedIntensity = light.intensity * fadeFactor; return evaluatedIntensity; } public void ApplyFade(bool _shadowsEnabled) { if (!(light == null)) { hdLightData.EnableShadows(_shadowsEnabled); hdLightData.lightDimmer = fadeFactor; hdLightData.shadowDimmer = shadowFadeFactor; hdLightData.volumetricDimmer = fadeFactor * volumetricMultiplier; hdLightData.volumetricShadowDimmer = shadowFadeFactor; } } public void ApplyFade() { ApplyFade(shadowEnabled); } } [SerializeField] private List celestialBodies = new List(); private List bodiesData; [SerializeField] private Vector2 startEndDecreaseAngle = new Vector3(-15f, -20f); private void Update() { EvaluateBodies(); SortBodies(); ApplyFade(); } private void EvaluateBodies() { foreach (CelestialBodyData bodiesDatum in bodiesData) { bodiesDatum.Evaluate(startEndDecreaseAngle.x, startEndDecreaseAngle.y); } } private void SortBodies() { bodiesData.Sort((CelestialBodyData a, CelestialBodyData b) => (!(a.evaluatedIntensity > b.evaluatedIntensity)) ? 1 : (-1)); } private void ApplyFade() { if (bodiesData.Count > 1) { bodiesData[0].fadeFactor = bodiesData[0].fadeFactor * 2f - 1f; bodiesData[1].fadeFactor = Mathf.Clamp01(0f - bodiesData[0].fadeFactor); bodiesData[0].fadeFactor = Mathf.Clamp01(bodiesData[0].fadeFactor); bodiesData[0].shadowEnabled = bodiesData[0].fadeFactor > 0f; bodiesData[1].shadowEnabled = bodiesData[1].fadeFactor > 0f; } for (int i = 0; i < bodiesData.Count; i++) { if (i > 1) { bodiesData[i].fadeFactor = 0f; bodiesData[i].shadowEnabled = false; } bodiesData[i].shadowFadeFactor = bodiesData[i].fadeFactor; bodiesData[i].ApplyFade(); } } private void OnValidate() { Init(); } private void OnEnable() { Init(); } private void Init() { bodiesData = new List(); foreach (Light celestialBody in celestialBodies) { bodiesData.Add(new CelestialBodyData(celestialBody)); } } public static float GetHorizonMultiplier(float angle, float fadeStart, float fadeEnd) { angle %= 360f; if (angle < 0f) { angle += 360f; } if (angle > 180f) { angle -= 360f; } float num = Mathf.Sign(angle); float num2 = Mathf.Abs(angle); if (num2 > 90f) { num2 = 90f - num2; } angle = num2 * num; return Mathf.Clamp01(Mathf.InverseLerp(fadeEnd, fadeStart, angle)); } }