Files
aibis-dream/Assets/Scripts/FixSystemNew/FixLightSystem/FixLightSystem.cs
T
2026-02-03 20:49:52 +08:00

923 lines
29 KiB
C#

using UnityEngine;
using UnityEngine.Rendering.Universal;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
namespace AibisDream.FixSystem
{
/// <summary>
/// 灯光系统控制器,管理呼吸灯、小灯、环境灯、面板灯和警报灯的状态
/// </summary>
public class FixLightSystem : MonoBehaviour
{
#region 枚举定义
/// <summary>
/// 灯光状态
/// </summary>
public enum LightState
{
Normal, // 正常状态
Warning, // 警告状态
Emergency // 紧急状态
}
/// <summary>
/// 小灯状态
/// </summary>
public enum SmallLightState
{
Default, // 默认状态
Operation // 运行状态
}
/// <summary>
/// 小灯状态状态
/// </summary>
public enum SmallLightStatus
{
Normal, // 正常
Error // 错误
}
#endregion
#region 常量定义
private const float SYSTEM_OFF_ENVIRONMENT_INTENSITY = 0.4f;
private const float SELF_CHECK_DELAY = 0.05f;
private const float SELF_CHECK_INTERVAL = 0.1f;
private const float ECG_WAVE_TOGGLE_DELAY = 0.1f;
private const float ECG_WAVE_FINAL_DELAY = 0.2f;
private const float BREATHING_LIGHT_START_DELAY = 0.5f;
private const float ALARM_LIGHT_MAX_INTENSITY = 4f;
private const float BREATHING_LIGHT_MAX_INTENSITY = 1f;
private const int SELF_CHECK_COUNT = 2;
private const int MIN_FLICKER_BLINK_COUNT = 2;
private const int MAX_FLICKER_BLINK_COUNT = 4;
private const float MIN_FLICKER_INTERVAL = 3f;
private const float MAX_FLICKER_INTERVAL = 8f;
#endregion
#region 呼吸灯相关字段
[Header("呼吸灯设置")]
[SerializeField] private Light2D breathingLight;
[SerializeField] private float normalBreathingSpeed = 1f;
[SerializeField] private float warningBreathingSpeed = 2f;
[SerializeField] private float emergencyBreathingSpeed = 3f;
[SerializeField] private Color normalColor = Color.green;
[SerializeField] private Color warningColor = Color.yellow;
[SerializeField] private Color emergencyColor = Color.red;
[SerializeField] private RobotECGWave ecgWave;
private SpriteRenderer breathingLightSprite;
private Tween breathingTween;
#endregion
#region 小灯相关字段
[Header("小灯设置")]
[SerializeField] private List<Light2D> smallLights = new List<Light2D>();
[SerializeField] private float smallLightBlinkInterval = 0.5f;
[SerializeField] private Color smallLightDefaultColor = Color.yellow;
[SerializeField] private Color smallLightNormalColor = Color.green;
[SerializeField] private Color smallLightErrorColor = Color.red;
[SerializeField] private float operationBlinkDuration = 1f;
[SerializeField] private float operationBlinkInterval = 0.1f;
private List<SpriteRenderer> smallLightSprites = new List<SpriteRenderer>();
private SmallLightState smallLightState = SmallLightState.Default;
private SmallLightStatus smallLightStatus = SmallLightStatus.Normal;
#endregion
#region 环境灯相关字段
[Header("环境灯设置")]
[SerializeField] private Light2D environmentLight;
[SerializeField] private bool isEnvironmentLightFlickering = false;
[SerializeField] private float normalEnvironmentIntensity = 1f;
[SerializeField] private float warningEnvironmentIntensity = 1f;
[SerializeField] private float emergencyEnvironmentIntensity = 1f;
[SerializeField] private float brokenLightFlickerInterval = 0.1f;
[SerializeField] private float brokenLightFlickerDuration = 0.05f;
[SerializeField] private float brokenLightPatternInterval = 2f;
[SerializeField] private float brokenLightDarkDuration = 0.8f;
[SerializeField] private Color normalEnvironmentColor = Color.white;
[SerializeField] private Color warningEnvironmentColor = Color.yellow;
[SerializeField] private Color emergencyEnvironmentColor = Color.red;
#endregion
#region 面板灯相关字段
[Header("面板灯设置")]
[SerializeField] private Light2D panelLight;
[SerializeField] private float panelLightIntensity = 1f;
[SerializeField] private float panelLightBlinkDuration = 0.2f;
[SerializeField] private int panelLightBlinkCount = 2;
[SerializeField] private Color panelLightColor = Color.white;
#endregion
#region 警报灯相关字段
[Header("警报灯设置")]
[SerializeField] private Light2D alarmLight;
[SerializeField] private float alarmBlinkSpeed = 0.5f;
[SerializeField] private Color alarmLightColor = Color.red;
private Tween alarmTween;
#endregion
#region 系统状态相关字段
[SerializeField] private bool isSystemOn = false;
private LightState currentState = LightState.Normal;
private bool isSystemStarting = false;
#endregion
#region Unity生命周期方法
private void Awake()
{
// 初始化SpriteRenderer引用
InitializeSpriteRenderers();
}
private void Start()
{
InitializeSystemState();
SetEnvironmentLightBroken();
SetEnvironmentLightFlickering(isEnvironmentLightFlickering);
StartCoroutine(SmallLightsBlinkRoutine());
SetSmallLightState(SmallLightState.Default);
}
private void OnDestroy()
{
// 清理所有Tween
breathingTween?.Kill();
alarmTween?.Kill();
}
#endregion
#region 初始化方法
/// <summary>
/// 初始化SpriteRenderer引用
/// </summary>
private void InitializeSpriteRenderers()
{
// 自动获取呼吸灯的SpriteRenderer
if (breathingLight != null)
{
breathingLightSprite = breathingLight.GetComponentInParent<SpriteRenderer>();
}
// 自动获取小灯的SpriteRenderer
smallLightSprites.Clear();
foreach (var light in smallLights)
{
if (light != null)
{
var spriteRenderer = light.GetComponentInParent<SpriteRenderer>();
smallLightSprites.Add(spriteRenderer);
}
}
}
/// <summary>
/// 初始化系统状态
/// </summary>
private void InitializeSystemState()
{
if (isSystemOn)
{
InitializeSystemOn();
}
else
{
InitializeSystemOff();
}
}
/// <summary>
/// 系统开启时的初始化
/// </summary>
private void InitializeSystemOn()
{
SetBreathingLight(normalColor, BREATHING_LIGHT_MAX_INTENSITY);
InitializeSmallLights(smallLightDefaultColor, BREATHING_LIGHT_MAX_INTENSITY);
SetPanelLight(panelLightColor, panelLightIntensity);
SetECGWaveActive(true);
SetEnvironmentLightIntensity(normalEnvironmentIntensity);
}
/// <summary>
/// 系统关闭时的初始化
/// </summary>
private void InitializeSystemOff()
{
SetBreathingLight(normalColor, 0f, true);
TurnOffAllSmallLights();
SetPanelLight(panelLightColor, 0f);
SetECGWaveActive(false);
SetEnvironmentLightIntensity(SYSTEM_OFF_ENVIRONMENT_INTENSITY);
}
#endregion
#region 公共方法 - 系统控制
/// <summary>
/// 检查系统是否开启
/// </summary>
public bool IsSystemOn()
{
return isSystemOn;
}
/// <summary>
/// 设置系统电源状态
/// </summary>
public void SetSystemPower(bool isOn)
{
isSystemOn = isOn;
if (!isOn)
{
TurnOffAllLights();
}
else
{
UpdateLightsState();
}
}
/// <summary>
/// 启动系统
/// </summary>
public IEnumerator StartSystem()
{
if (isSystemStarting || isSystemOn) yield break;
isSystemStarting = true;
yield return StartCoroutine(SystemStartSequence());
isSystemStarting = false;
}
#endregion
#region 公共方法 - 灯光状态控制
/// <summary>
/// 设置灯光状态
/// </summary>
public void SetLightState(LightState newState)
{
if (!isSystemOn) return;
if (currentState != newState)
{
currentState = newState;
UpdateLightsState();
Debug.Log($"灯光状态已切换为: {newState}");
}
}
/// <summary>
/// 设置小灯状态
/// </summary>
public void SetSmallLightState(SmallLightState newState)
{
if (smallLightState != newState)
{
smallLightState = newState;
if (newState == SmallLightState.Default)
{
smallLightStatus = SmallLightStatus.Normal;
}
StartCoroutine(HandleSmallLightStateChange());
}
}
/// <summary>
/// 设置小灯状态状态
/// </summary>
public void SetSmallLightStatus(SmallLightStatus newStatus)
{
if (smallLightStatus != newStatus)
{
smallLightStatus = newStatus;
UpdateSmallLightsStatus();
}
}
/// <summary>
/// 设置环境灯闪烁状态
/// </summary>
public void SetEnvironmentLightFlickering(bool isFlickering)
{
if (isEnvironmentLightFlickering != isFlickering)
{
isEnvironmentLightFlickering = isFlickering;
if (isFlickering)
{
StartCoroutine(EnvironmentLightFlickerRoutine());
}
}
}
/// <summary>
/// 设置环境灯损坏状态
/// </summary>
public void SetEnvironmentLightBroken()
{
if (environmentLight != null)
{
environmentLight.color = GetEnvironmentColorByState(currentState);
}
}
/// <summary>
/// 设置警报灯闪烁速度
/// </summary>
public void SetAlarmBlinkSpeed(float speed)
{
if (speed > 0)
{
alarmBlinkSpeed = speed;
// 如果当前正在闪烁,更新闪烁速度
if (currentState == LightState.Emergency && alarmLight != null)
{
StartAlarmLightBlink();
}
}
}
/// <summary>
/// 停止警报灯
/// </summary>
public void StopAlarmLight()
{
if (alarmLight != null)
{
alarmTween?.Kill();
alarmLight.intensity = 0f;
}
}
#endregion
#region 公共方法 - ECG波形控制
/// <summary>
/// 获取当前波形类型
/// </summary>
public RobotECGWave.WaveType GetCurrentWaveType()
{
return ecgWave?.waveType ?? RobotECGWave.WaveType.RobotECG;
}
/// <summary>
/// 设置波形类型
/// </summary>
public void SetWaveType(RobotECGWave.WaveType waveType)
{
if (ecgWave != null)
{
ecgWave.SetWaveType(waveType);
}
}
#endregion
#region 私有方法 - 灯光状态更新
/// <summary>
/// 更新所有灯光状态
/// </summary>
private void UpdateLightsState()
{
var stateConfig = GetStateConfig(currentState);
UpdateAlarmLight(stateConfig);
UpdateBreathingLight(stateConfig);
UpdateECGWave(stateConfig);
UpdateEnvironmentLight(stateConfig);
}
/// <summary>
/// 获取状态配置
/// </summary>
private (Color color, float breathingSpeed, RobotECGWave.WaveType waveType, Color envColor, float envIntensity) GetStateConfig(LightState state)
{
return state switch
{
LightState.Normal => (normalColor, normalBreathingSpeed, RobotECGWave.WaveType.RobotECG, normalEnvironmentColor, normalEnvironmentIntensity),
LightState.Warning => (warningColor, warningBreathingSpeed, RobotECGWave.WaveType.Warning, warningEnvironmentColor, warningEnvironmentIntensity),
LightState.Emergency => (emergencyColor, emergencyBreathingSpeed, RobotECGWave.WaveType.Noise, normalEnvironmentColor, normalEnvironmentIntensity),
_ => (normalColor, normalBreathingSpeed, RobotECGWave.WaveType.RobotECG, normalEnvironmentColor, normalEnvironmentIntensity)
};
}
/// <summary>
/// 更新警报灯
/// </summary>
private void UpdateAlarmLight((Color color, float breathingSpeed, RobotECGWave.WaveType waveType, Color envColor, float envIntensity) config)
{
if (alarmLight == null) return;
if (currentState == LightState.Emergency)
{
alarmLight.color = alarmLightColor;
StartAlarmLightBlink();
}
else
{
StopAlarmLight();
}
}
/// <summary>
/// 启动警报灯闪烁
/// </summary>
private void StartAlarmLightBlink()
{
if (alarmLight == null) return;
alarmTween?.Kill();
alarmTween = DOTween.To(
() => alarmLight.intensity,
x => alarmLight.intensity = x,
ALARM_LIGHT_MAX_INTENSITY,
alarmBlinkSpeed
)
.SetLoops(-1, LoopType.Yoyo)
.SetEase(Ease.InOutSine);
}
/// <summary>
/// 更新呼吸灯
/// </summary>
private void UpdateBreathingLight((Color color, float breathingSpeed, RobotECGWave.WaveType waveType, Color envColor, float envIntensity) config)
{
if (breathingLight == null)
{
Debug.LogWarning("呼吸灯组件未设置!");
return;
}
SetBreathingLight(config.color, BREATHING_LIGHT_MAX_INTENSITY);
StartBreathingEffect(config.breathingSpeed);
}
/// <summary>
/// 启动呼吸效果
/// </summary>
private void StartBreathingEffect(float breathingSpeed)
{
breathingTween?.Kill();
breathingTween = DOTween.To(
() => breathingLight.intensity,
x => breathingLight.intensity = x,
BREATHING_LIGHT_MAX_INTENSITY,
1f / breathingSpeed
)
.SetLoops(-1, LoopType.Yoyo)
.SetEase(Ease.InOutSine);
}
/// <summary>
/// 更新ECG波形
/// </summary>
private void UpdateECGWave((Color color, float breathingSpeed, RobotECGWave.WaveType waveType, Color envColor, float envIntensity) config)
{
if (ecgWave != null)
{
ecgWave.SetWaveType(config.waveType);
}
else
{
Debug.LogWarning("ECG波形组件未设置!");
}
}
/// <summary>
/// 更新环境灯
/// </summary>
private void UpdateEnvironmentLight((Color color, float breathingSpeed, RobotECGWave.WaveType waveType, Color envColor, float envIntensity) config)
{
if (environmentLight == null) return;
environmentLight.color = config.envColor;
float targetIntensity = isSystemOn ? config.envIntensity : SYSTEM_OFF_ENVIRONMENT_INTENSITY;
environmentLight.intensity = targetIntensity;
}
#endregion
#region 私有方法 - 灯光设置辅助方法
/// <summary>
/// 设置呼吸灯
/// </summary>
private void SetBreathingLight(Color color, float intensity, bool useTransparent = false)
{
if (breathingLight != null)
{
breathingLight.color = color;
breathingLight.intensity = intensity;
}
if (breathingLightSprite != null)
{
breathingLightSprite.color = useTransparent
? new Color(color.r, color.g, color.b, 0f)
: color;
}
}
/// <summary>
/// 设置面板灯
/// </summary>
private void SetPanelLight(Color color, float intensity)
{
if (panelLight != null)
{
panelLight.color = color;
panelLight.intensity = intensity;
}
}
/// <summary>
/// 设置环境灯强度
/// </summary>
private void SetEnvironmentLightIntensity(float intensity)
{
if (environmentLight != null)
{
environmentLight.intensity = intensity;
}
}
/// <summary>
/// 设置ECG波形激活状态
/// </summary>
private void SetECGWaveActive(bool active)
{
if (ecgWave != null)
{
ecgWave.gameObject.SetActive(active);
}
}
/// <summary>
/// 初始化小灯
/// </summary>
private void InitializeSmallLights(Color color, float intensity)
{
SetSmallLightsColorAndIntensity(color, intensity);
}
/// <summary>
/// 设置小灯颜色和强度
/// </summary>
private void SetSmallLightsColorAndIntensity(Color color, float intensity)
{
for (int i = 0; i < smallLights.Count; i++)
{
if (smallLights[i] != null)
{
smallLights[i].color = color;
smallLights[i].intensity = intensity;
}
if (i < smallLightSprites.Count && smallLightSprites[i] != null)
{
smallLightSprites[i].color = color;
}
}
}
/// <summary>
/// 关闭所有小灯
/// </summary>
private void TurnOffAllSmallLights()
{
SetSmallLightsColorAndIntensity(Color.clear, 0f);
}
/// <summary>
/// 关闭所有灯光
/// </summary>
private void TurnOffAllLights()
{
SetBreathingLight(normalColor, 0f, true);
SetPanelLight(panelLightColor, 0f);
SetECGWaveActive(false);
TurnOffAllSmallLights();
}
/// <summary>
/// 根据状态获取环境灯颜色
/// </summary>
private Color GetEnvironmentColorByState(LightState state)
{
return state switch
{
LightState.Normal => normalEnvironmentColor,
LightState.Warning => warningEnvironmentColor,
LightState.Emergency => emergencyEnvironmentColor,
_ => normalEnvironmentColor
};
}
#endregion
#region 私有方法 - 小灯相关
/// <summary>
/// 处理小灯状态变化
/// </summary>
private IEnumerator HandleSmallLightStateChange()
{
if (smallLightState == SmallLightState.Operation)
{
yield return StartCoroutine(OperationBlinkSequence());
SetSmallLightsToOperationState();
}
else
{
ResetSmallLightsToDefault();
}
}
/// <summary>
/// 运行状态闪烁序列
/// </summary>
private IEnumerator OperationBlinkSequence()
{
float endTime = Time.time + operationBlinkDuration;
while (Time.time < endTime)
{
foreach (var light in smallLights)
{
if (light != null)
{
light.intensity = Random.value > 0.5f ? BREATHING_LIGHT_MAX_INTENSITY : 0f;
}
}
yield return new WaitForSeconds(operationBlinkInterval);
}
}
/// <summary>
/// 设置小灯为运行状态
/// </summary>
private void SetSmallLightsToOperationState()
{
Color targetColor = GetSmallLightColorByState(currentState);
SetSmallLightsColorAndIntensity(targetColor, BREATHING_LIGHT_MAX_INTENSITY);
}
/// <summary>
/// 根据当前状态获取小灯颜色
/// </summary>
private Color GetSmallLightColorByState(LightState state)
{
return state switch
{
LightState.Normal => smallLightNormalColor,
LightState.Warning => warningColor,
LightState.Emergency => emergencyColor,
_ => smallLightNormalColor
};
}
/// <summary>
/// 重置小灯为默认状态
/// </summary>
private void ResetSmallLightsToDefault()
{
SetSmallLightsColorAndIntensity(smallLightDefaultColor, 0f);
// 只有第一个灯闪烁
if (smallLights.Count > 0 && smallLights[0] != null)
{
smallLights[0].intensity = BREATHING_LIGHT_MAX_INTENSITY;
if (smallLightSprites.Count > 0 && smallLightSprites[0] != null)
{
smallLightSprites[0].color = smallLightDefaultColor;
}
}
}
/// <summary>
/// 更新小灯状态状态
/// </summary>
private void UpdateSmallLightsStatus()
{
Color targetColor = smallLightStatus == SmallLightStatus.Normal
? smallLightNormalColor
: smallLightErrorColor;
SetSmallLightsColorAndIntensity(targetColor, BREATHING_LIGHT_MAX_INTENSITY);
}
/// <summary>
/// 小灯闪烁协程
/// </summary>
private IEnumerator SmallLightsBlinkRoutine()
{
while (true)
{
if (!isSystemOn)
{
TurnOffAllSmallLights();
}
else if (smallLightState == SmallLightState.Default)
{
ResetSmallLightsToDefault();
}
yield return new WaitForSeconds(smallLightBlinkInterval);
}
}
#endregion
#region 私有方法 - 环境灯相关
/// <summary>
/// 环境灯闪烁协程
/// </summary>
private IEnumerator EnvironmentLightFlickerRoutine()
{
while (isEnvironmentLightFlickering)
{
if (environmentLight == null)
{
yield return new WaitForSeconds(0.1f);
continue;
}
float currentIntensity = GetEnvironmentIntensityByState(currentState);
environmentLight.intensity = currentIntensity;
// 等待随机间隔
yield return new WaitForSeconds(Random.Range(MIN_FLICKER_INTERVAL, MAX_FLICKER_INTERVAL));
// 随机闪烁
int blinkCount = Random.Range(MIN_FLICKER_BLINK_COUNT, MAX_FLICKER_BLINK_COUNT);
for (int i = 0; i < blinkCount; i++)
{
environmentLight.intensity = 0f;
yield return new WaitForSeconds(brokenLightFlickerDuration);
environmentLight.intensity = currentIntensity;
yield return new WaitForSeconds(brokenLightFlickerInterval);
}
}
// 确保灯光在停止闪烁时是亮着的
if (environmentLight != null)
{
environmentLight.intensity = GetEnvironmentIntensityByState(currentState);
}
}
/// <summary>
/// 根据状态获取环境灯强度
/// </summary>
private float GetEnvironmentIntensityByState(LightState state)
{
return state switch
{
LightState.Normal => normalEnvironmentIntensity,
LightState.Warning => warningEnvironmentIntensity,
LightState.Emergency => emergencyEnvironmentIntensity,
_ => normalEnvironmentIntensity
};
}
#endregion
#region 私有方法 - 系统启动序列
/// <summary>
/// 系统启动序列
/// </summary>
private IEnumerator SystemStartSequence()
{
// 1. ECG波形闪烁
yield return StartCoroutine(ECGWaveToggleSequence());
// 2. 小灯自检
yield return StartCoroutine(SmallLightsSelfCheck());
// 3. 启动呼吸灯
SetBreathingLight(normalColor, BREATHING_LIGHT_MAX_INTENSITY);
yield return new WaitForSeconds(BREATHING_LIGHT_START_DELAY);
// 4. 启动面板灯
yield return StartCoroutine(PanelLightStartSequence());
// 5. 设置系统状态为开启
SetSystemPower(true);
}
/// <summary>
/// ECG波形闪烁序列
/// </summary>
private IEnumerator ECGWaveToggleSequence()
{
if (ecgWave == null) yield break;
ecgWave.gameObject.SetActive(true);
yield return new WaitForSeconds(ECG_WAVE_TOGGLE_DELAY);
ecgWave.gameObject.SetActive(false);
yield return new WaitForSeconds(ECG_WAVE_TOGGLE_DELAY);
ecgWave.gameObject.SetActive(true);
yield return new WaitForSeconds(ECG_WAVE_FINAL_DELAY);
}
/// <summary>
/// 面板灯启动序列
/// </summary>
private IEnumerator PanelLightStartSequence()
{
if (panelLight == null) yield break;
for (int i = 0; i < panelLightBlinkCount; i++)
{
// 渐亮
DOTween.To(() => panelLight.intensity, x => panelLight.intensity = x, panelLightIntensity, panelLightBlinkDuration * 0.5f)
.SetEase(Ease.InOutQuad);
DOTween.To(() => environmentLight.intensity, x => environmentLight.intensity = x, normalEnvironmentIntensity, panelLightBlinkDuration * 0.5f)
.SetEase(Ease.InOutQuad);
yield return new WaitForSeconds(panelLightBlinkDuration);
// 渐暗
DOTween.To(() => panelLight.intensity, x => panelLight.intensity = x, 0f, panelLightBlinkDuration * 0.5f)
.SetEase(Ease.InOutQuad);
DOTween.To(() => environmentLight.intensity, x => environmentLight.intensity = x, 0f, panelLightBlinkDuration * 0.5f)
.SetEase(Ease.InOutQuad);
yield return new WaitForSeconds(panelLightBlinkDuration);
}
// 最后渐亮到常亮状态
DOTween.To(() => panelLight.intensity, x => panelLight.intensity = x, panelLightIntensity, panelLightBlinkDuration * 0.5f)
.SetEase(Ease.InOutQuad);
DOTween.To(() => environmentLight.intensity, x => environmentLight.intensity = x, normalEnvironmentIntensity, panelLightBlinkDuration * 0.5f)
.SetEase(Ease.InOutQuad);
}
/// <summary>
/// 小灯自检序列
/// </summary>
private IEnumerator SmallLightsSelfCheck()
{
// 关闭所有小灯
SetSmallLightsColorAndIntensity(Color.clear, 0f);
// 自检两次
for (int check = 0; check < SELF_CHECK_COUNT; check++)
{
// 从左到右点亮
for (int i = 0; i < smallLights.Count; i++)
{
if (smallLights[i] != null)
{
smallLights[i].color = smallLightDefaultColor;
smallLights[i].intensity = BREATHING_LIGHT_MAX_INTENSITY;
}
if (i < smallLightSprites.Count && smallLightSprites[i] != null)
{
smallLightSprites[i].color = smallLightDefaultColor;
}
yield return new WaitForSeconds(SELF_CHECK_DELAY);
}
// 关闭所有灯
SetSmallLightsColorAndIntensity(Color.clear, 0f);
yield return new WaitForSeconds(SELF_CHECK_INTERVAL);
}
// 恢复到默认状态(只有第一个灯闪烁)
ResetSmallLightsToDefault();
}
#endregion
}
}