Ultimate_Light_Manager.cs
using Sandbox;
using System;
using System.Collections.Generic;
[Title( "Ultimate Light Manager" )]
[Category( "Light" )]
[Icon( "light_mode" )]
public class LightManager : Component, Component.ExecuteInEditor
{
[Property, Group("General"), Title("Light Color")]
public Color LightColor { get; set; } = Color.White;
[Property, Group("General"), Title("Max Brightness")]
public float TargetBrightness { get; set; } = 1.0f;
[Property, Group("General"), Title("Start Enabled")]
public bool IsEnabled { get; set; } = true;
[Property, Group("General"), Title("Interaction (Click)")]
public bool Clickable { get; set; } = true;
[Property, Group("Motion Sensor"), Title("Enable Sensor")]
public bool SensorEnabled { get; set; } = false;
[Property, Group("Motion Sensor")]
public float SensorRange { get; set; } = 200.0f;
[Property, Group("Motion Sensor")]
public float SensorFadeSpeed { get; set; } = 2.0f;
[Property, Group("Disco Mode")] public bool DiscoMode { get; set; } = false;
[Property, Group("Disco Mode")] public float DiscoSpeed { get; set; } = 20.0f;
[Property, Group("Disco Mode")] public float RainbowSpeed { get; set; } = 5.0f;
[Property, Group("Horror Mode")] public bool HorrorMode { get; set; } = false;
[Property, Group("Horror Mode")] public float HorrorStability { get; set; } = 0.7f;
[Property, Group("Fire Mode")] public bool FireMode { get; set; } = false;
[Property, Group("Fire Mode")] public float FireSpeed { get; set; } = 10.0f;
[Property, Group("Fire Mode")] public float FireIntensity { get; set; } = 0.1f;
[Property, Group("Blink Mode")] public bool BlinkEnabled { get; set; } = false;
[Property, Group("Blink Mode")] public float BlinkInterval { get; set; } = 0.5f;
[Property, Group("Color Cycle")] public bool CycleEnabled { get; set; } = false;
[Property, Group("Color Cycle")] public List<Color> CycleColors { get; set; } = new List<Color>();
[Property, Group("Color Cycle")] public float ColorDuration { get; set; } = 2.0f;
[Property, Group("Audio"), Title("Turn On Sound")]
[Description("Sound played when the light turns on.")]
public SoundEvent SoundOn { get; set; }
[Property, Group("Audio"), Title("Turn Off Sound")]
[Description("Sound played when the light turns off.")]
public SoundEvent SoundOff { get; set; }
[Property, Group("Audio"), Title("Ambient Sound (Loop)")]
[Description("Sound played continuously (e.g., Neon hum, Fire crackle).")]
public SoundEvent SoundLoop { get; set; }
[Property, Group("Audio"), Title("Ambient Volume")]
[Range(0f, 1f)]
public float LoopVolume { get; set; } = 1.0f;
[RequireComponent] public PointLight LightComponent { get; private set; }
private float _sensorFactor = 1.0f;
private SoundHandle _loopHandle;
private bool _wasEnabled;
protected override void OnStart()
{
_wasEnabled = IsEnabled;
}
protected override void OnUpdate()
{
if ( LightComponent == null ) return;
CheckInteraction();
UpdateMotionSensor();
UpdateAudioSystem();
Color finalColor = CalculateColor();
float finalBrightness = CalculateBrightness();
float totalBrightness = finalBrightness * _sensorFactor;
LightComponent.LightColor = finalColor * totalBrightness;
LightComponent.Enabled = IsEnabled && _sensorFactor > 0.01f;
}
protected override void OnDestroy()
{
_loopHandle?.Stop();
}
private void UpdateAudioSystem()
{
if ( IsEnabled != _wasEnabled )
{
if ( IsEnabled )
{
if ( SoundOn != null ) Sound.Play( SoundOn, Transform.Position );
}
else
{
if ( SoundOff != null ) Sound.Play( SoundOff, Transform.Position );
}
_wasEnabled = IsEnabled;
}
if ( IsEnabled && SoundLoop != null )
{
if ( !_loopHandle.IsValid() )
_loopHandle = Sound.Play( SoundLoop, Transform.Position );
_loopHandle.Position = Transform.Position;
_loopHandle.Volume = LoopVolume * _sensorFactor;
}
else
{
_loopHandle?.Stop();
}
}
private void UpdateMotionSensor()
{
if ( !SensorEnabled ) { _sensorFactor = 1.0f; return; }
if ( Scene.Camera == null ) return;
float dist = GameObject.Transform.Position.Distance( Scene.Camera.Transform.Position );
float target = (dist < SensorRange) ? 1.0f : 0.0f;
_sensorFactor = MathX.Lerp( _sensorFactor, target, Time.Delta * SensorFadeSpeed );
}
private void CheckInteraction()
{
if ( !Clickable || Scene.Camera == null ) return;
if ( Input.Pressed( "attack1" ) )
{
var ray = Scene.Camera.ScreenPixelToRay( Mouse.Position );
var tr = Scene.Trace.Ray( ray, 5000f ).IgnoreGameObjectHierarchy( Scene.Camera.GameObject ).Run();
if ( tr.Hit && tr.GameObject == GameObject ) IsEnabled = !IsEnabled;
}
}
private Color CalculateColor()
{
if ( DiscoMode ) return new ColorHsv( (Time.Now * RainbowSpeed * 50f) % 360f, 1, 1 ).ToColor();
if ( CycleEnabled && CycleColors != null && CycleColors.Count > 1 )
{
float duration = Math.Max( ColorDuration, 0.1f );
float r = Time.Now / duration;
return Color.Lerp( CycleColors[(int)r % CycleColors.Count], CycleColors[((int)r + 1) % CycleColors.Count], r - (float)Math.Floor(r) );
}
return LightColor;
}
private float CalculateBrightness()
{
if ( !IsEnabled ) return 0.0f;
if ( DiscoMode ) return (MathF.Sin( Time.Now * DiscoSpeed ) > 0) ? TargetBrightness : 0f;
if ( HorrorMode && Game.Random.Float(0,1) > HorrorStability ) return Game.Random.Float(0,1) > 0.5f ? 0f : TargetBrightness * 0.1f;
if ( FireMode ) {
float noise = (MathF.Sin(Time.Now*FireSpeed) + MathF.Sin(Time.Now*FireSpeed*0.5f)) / 2f;
return Math.Max(0, TargetBrightness + (noise * FireIntensity));
}
if ( BlinkEnabled ) {
float i = Math.Max(BlinkInterval, 0.05f);
return ((Time.Now % (i*2)) < i) ? TargetBrightness : 0f;
}
return TargetBrightness;
}
}