Code/LightTemperature.cs
using Sandbox;
namespace RotSoft.Lighting;
/// <summary>
/// Adjusts the <see cref="Color"/> of a <see cref="Light"/> component using Color <see cref="Temperature"/> in Kelvin.
/// Applies once on add and whenever the temperature or brightness changes, so the light's color stays manually editable.
/// </summary>
[Title( "Light Temperature" )]
[Category( "Light" )]
[Icon( "thermostat" )]
[Alias( "Temperature", "Kelvin" )]
public sealed class LightTemperature : Component, Component.ExecuteInEditor
{
/// <summary>Common light temperature presets in Kelvin.</summary>
public enum LightTemperaturePreset
{
/// <summary>1000 K</summary>
MatchFlame = 1700,
/// <summary>2400 K</summary>
Incandescent = 2400,
/// <summary>2700 K</summary>
WarmWhite = 3000,
/// <summary>3200 K</summary>
Studio = 3200,
/// <summary>5000 K</summary>
CoolWhite = 5000,
/// <summary>6500 K</summary>
Daylight = 6500,
/// <summary>6500 K</summary>
LCD = 9500,
/// <summary>7500 K</summary>
BlueSky = 15000,
/// <summary>Custom value, set it with the Kelvin slider.</summary>
Custom = 0,
}
LightTemperaturePreset _preset = LightTemperaturePreset.CoolWhite;
float _kelvin = 5000f;
float _brightness = 1f;
bool _syncing;
Light _light;
/// <summary>Standard light temperature presets.</summary>
[Property]
public LightTemperaturePreset Preset
{
get => _preset;
set
{
if ( _preset == value ) return;
_preset = value;
if ( value != LightTemperaturePreset.Custom )
{
_syncing = true;
Kelvin = (float)(int)value;
_syncing = false;
}
else
{
ApplyColor();
}
}
}
/// <summary>The color temperature in Kelvin.</summary>
[Property, Title( "Temperature (K)" ), Range( 1500, 15000 ), KelvinSlider]
public float Kelvin
{
get => _kelvin;
set
{
if ( _kelvin == value ) return;
_kelvin = value;
if ( !_syncing && _preset != LightTemperaturePreset.Custom )
_preset = LightTemperaturePreset.Custom;
ApplyColor();
}
}
/// <summary>The brightness (range) of the Light.</summary>
[Property, Range( 0, 5f ), Step( 0.01f )]
public float Brightness
{
get => _brightness;
set
{
if ( _brightness == value ) return;
_brightness = value;
ApplyColor();
}
}
/// <summary>Applies the current temperature and brightness to the <see cref="Light"/>'s color once on add.</summary>
protected override void OnStart()
{
ApplyColor();
}
/// <summary>Sets the <see cref="Light"/>'s color from the current temperature and brightness, if a light is present.</summary>
void ApplyColor()
{
_light ??= GetComponentInChildren<Light>( true );
if ( _light is null ) return;
_light.LightColor = new Temperature( Kelvin ).ToColor() * Brightness;
}
}