Files
Bombaleila/Assets/ThunderWire Studio/UHFPS/Content/Scripts/Runtime/Interact/Lights/SwitcherLight.cs
2026-03-03 05:27:03 +05:00

142 lines
4.3 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UHFPS.Tools;
using ThunderWire.Attributes;
using Newtonsoft.Json.Linq;
using static UHFPS.Runtime.InteractableLight;
namespace UHFPS.Runtime
{
[InspectorHeader("Switcher Light")]
public class SwitcherLight : MonoBehaviour, IInteractStart, ISaveable
{
public bool IsSwitchedOn;
[Header("References")]
public List<Light> LightComponents = new();
public List<MeshRenderer> MeshRenderers = new();
[Header("Light")]
public bool SmoothLight;
public float SmoothDuration;
[Header("Emission")]
public bool EnableEmission = true;
public string EmissionKeyword = "_EMISSION";
[Header("Sounds")]
public SoundClip LightSwitchOn;
public SoundClip LightSwitchOff;
[Space, Boxed("AnimationWindowEvent Icon", title = "Light Events")]
public LightEventsStruct LightEvents = new();
private LightComponent[] lightComponents;
private void Awake()
{
lightComponents = new LightComponent[LightComponents.Count];
for (int i = 0; i < LightComponents.Count; i++)
{
lightComponents[i] = new LightComponent()
{
light = LightComponents[i],
intensity = LightComponents[i].intensity,
current = LightComponents[i].intensity
};
}
SetLightState(IsSwitchedOn);
}
public void InteractStart()
{
if (IsSwitchedOn = !IsSwitchedOn)
{
SetLightState(true);
GameTools.PlayOneShot3D(transform.position, LightSwitchOn, "Lamp On");
LightEvents.OnLightOn?.Invoke();
}
else
{
SetLightState(false);
GameTools.PlayOneShot3D(transform.position, LightSwitchOff, "Lamp Off");
LightEvents.OnLightOff?.Invoke();
}
}
public void SetLightState(bool state)
{
if (!SmoothLight) LightComponents.ForEach(x => x.enabled = state);
else
{
StopAllCoroutines();
StartCoroutine(SwitchLightSmoothly(state));
}
foreach (var renderer in MeshRenderers)
{
if (state) renderer.material.EnableKeyword(EmissionKeyword);
else renderer.material.DisableKeyword(EmissionKeyword);
}
IsSwitchedOn = state;
}
IEnumerator SwitchLightSmoothly(bool state)
{
float elapsedTime = 0;
// set current light intensity
foreach (var light in lightComponents)
{
light.current = light.light.intensity;
if (state)
{
light.light.intensity = 0f;
light.light.enabled = true;
}
}
// lerp light intensity smoothly
while (elapsedTime < SmoothDuration)
{
elapsedTime += Time.deltaTime;
float t = Mathf.SmoothStep(0f, 1f, elapsedTime / SmoothDuration);
foreach (var light in lightComponents)
{
float target = state ? light.intensity : 0f;
light.light.intensity = Mathf.Lerp(light.current, target, t);
}
yield return null;
}
// disable light after lerping
if (!state)
{
foreach (var light in lightComponents)
{
light.current = 0f;
light.light.enabled = false;
}
}
}
public StorableCollection OnSave()
{
return new StorableCollection()
{
{ "lightState", IsSwitchedOn }
};
}
public void OnLoad(JToken data)
{
bool lightState = (bool)data["lightState"];
SetLightState(lightState);
}
}
}