Files
2026-03-04 09:37:33 +08:00

166 lines
3.5 KiB
C#

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<HDAdditionalLightData>();
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<Light> celestialBodies = new List<Light>();
private List<CelestialBodyData> 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<CelestialBodyData>();
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));
}
}