using UnityEngine; using UnityEngine.Rendering.Universal; using System.Collections; using System.Collections.Generic; using DG.Tweening; namespace AibisDream.FixSystem { /// /// 灯光系统控制器,管理呼吸灯、小灯、环境灯、面板灯和警报灯的状态 /// public class FixLightSystem : MonoBehaviour { #region 枚举定义 /// /// 灯光状态 /// public enum LightState { Normal, // 正常状态 Warning, // 警告状态 Emergency // 紧急状态 } #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 smallLights = new List(); [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 smallLightSprites = new List(); 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 初始化方法 /// /// 初始化SpriteRenderer引用 /// private void InitializeSpriteRenderers() { // 自动获取呼吸灯的SpriteRenderer if (breathingLight != null) { breathingLightSprite = breathingLight.GetComponentInParent(); } // 自动获取小灯的SpriteRenderer smallLightSprites.Clear(); foreach (var light in smallLights) { if (light != null) { var spriteRenderer = light.GetComponentInParent(); smallLightSprites.Add(spriteRenderer); } } } /// /// 初始化系统状态 /// private void InitializeSystemState() { if (isSystemOn) { InitializeSystemOn(); } else { InitializeSystemOff(); } } /// /// 系统开启时的初始化 /// private void InitializeSystemOn() { SetBreathingLight(normalColor, BREATHING_LIGHT_MAX_INTENSITY); InitializeSmallLights(smallLightDefaultColor, BREATHING_LIGHT_MAX_INTENSITY); SetPanelLight(panelLightColor, panelLightIntensity); SetECGWaveActive(true); SetEnvironmentLightIntensity(normalEnvironmentIntensity); } /// /// 系统关闭时的初始化 /// private void InitializeSystemOff() { SetBreathingLight(normalColor, 0f, true); TurnOffAllSmallLights(); SetPanelLight(panelLightColor, 0f); SetECGWaveActive(false); SetEnvironmentLightIntensity(SYSTEM_OFF_ENVIRONMENT_INTENSITY); } #endregion #region 公共方法 - 系统控制 /// /// 检查系统是否开启 /// public bool IsSystemOn() { return isSystemOn; } /// /// 设置系统电源状态 /// public void SetSystemPower(bool isOn) { isSystemOn = isOn; if (!isOn) { TurnOffAllLights(); } else { UpdateLightsState(); } } /// /// 启动系统 /// public IEnumerator StartSystem() { if (isSystemStarting || isSystemOn) yield break; isSystemStarting = true; yield return StartCoroutine(SystemStartSequence()); isSystemStarting = false; } #endregion #region 公共方法 - 灯光状态控制 /// /// 设置灯光状态 /// public void SetLightState(LightState newState) { if (!isSystemOn) return; if (currentState != newState) { currentState = newState; UpdateLightsState(); Debug.Log($"灯光状态已切换为: {newState}"); } } /// /// 设置小灯状态 /// public void SetSmallLightState(SmallLightState newState) { if (smallLightState != newState) { smallLightState = newState; if (newState == SmallLightState.Default) { smallLightStatus = SmallLightStatus.Normal; } StartCoroutine(HandleSmallLightStateChange()); } } /// /// 设置小灯状态状态 /// public void SetSmallLightStatus(SmallLightStatus newStatus) { if (smallLightStatus != newStatus) { smallLightStatus = newStatus; UpdateSmallLightsStatus(); } } /// /// 设置环境灯闪烁状态 /// public void SetEnvironmentLightFlickering(bool isFlickering) { if (isEnvironmentLightFlickering != isFlickering) { isEnvironmentLightFlickering = isFlickering; if (isFlickering) { StartCoroutine(EnvironmentLightFlickerRoutine()); } } } /// /// 设置环境灯损坏状态 /// public void SetEnvironmentLightBroken() { if (environmentLight != null) { environmentLight.color = GetEnvironmentColorByState(currentState); } } /// /// 设置警报灯闪烁速度 /// public void SetAlarmBlinkSpeed(float speed) { if (speed > 0) { alarmBlinkSpeed = speed; // 如果当前正在闪烁,更新闪烁速度 if (currentState == LightState.Emergency && alarmLight != null) { StartAlarmLightBlink(); } } } /// /// 停止警报灯 /// public void StopAlarmLight() { if (alarmLight != null) { alarmTween?.Kill(); alarmLight.intensity = 0f; } } #endregion #region 公共方法 - ECG波形控制 /// /// 获取当前波形类型 /// public RobotECGWave.WaveType GetCurrentWaveType() { return ecgWave?.waveType ?? RobotECGWave.WaveType.RobotECG; } /// /// 设置波形类型 /// public void SetWaveType(RobotECGWave.WaveType waveType) { if (ecgWave != null) { ecgWave.SetWaveType(waveType); } } #endregion #region 私有方法 - 灯光状态更新 /// /// 更新所有灯光状态 /// private void UpdateLightsState() { var stateConfig = GetStateConfig(currentState); UpdateAlarmLight(stateConfig); UpdateBreathingLight(stateConfig); UpdateECGWave(stateConfig); UpdateEnvironmentLight(stateConfig); } /// /// 获取状态配置 /// 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) }; } /// /// 更新警报灯 /// 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(); } } /// /// 启动警报灯闪烁 /// 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); } /// /// 更新呼吸灯 /// 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); } /// /// 启动呼吸效果 /// 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); } /// /// 更新ECG波形 /// 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波形组件未设置!"); } } /// /// 更新环境灯 /// 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 私有方法 - 灯光设置辅助方法 /// /// 设置呼吸灯 /// 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; } } /// /// 设置面板灯 /// private void SetPanelLight(Color color, float intensity) { if (panelLight != null) { panelLight.color = color; panelLight.intensity = intensity; } } /// /// 设置环境灯强度 /// private void SetEnvironmentLightIntensity(float intensity) { if (environmentLight != null) { environmentLight.intensity = intensity; } } /// /// 设置ECG波形激活状态 /// private void SetECGWaveActive(bool active) { if (ecgWave != null) { ecgWave.gameObject.SetActive(active); } } /// /// 初始化小灯 /// private void InitializeSmallLights(Color color, float intensity) { SetSmallLightsColorAndIntensity(color, intensity); } /// /// 设置小灯颜色和强度 /// 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; } } } /// /// 关闭所有小灯 /// private void TurnOffAllSmallLights() { SetSmallLightsColorAndIntensity(Color.clear, 0f); } /// /// 关闭所有灯光 /// private void TurnOffAllLights() { SetBreathingLight(normalColor, 0f, true); SetPanelLight(panelLightColor, 0f); SetECGWaveActive(false); TurnOffAllSmallLights(); } /// /// 根据状态获取环境灯颜色 /// private Color GetEnvironmentColorByState(LightState state) { return state switch { LightState.Normal => normalEnvironmentColor, LightState.Warning => warningEnvironmentColor, LightState.Emergency => emergencyEnvironmentColor, _ => normalEnvironmentColor }; } #endregion #region 私有方法 - 小灯相关 /// /// 处理小灯状态变化 /// private IEnumerator HandleSmallLightStateChange() { if (smallLightState == SmallLightState.Operation) { yield return StartCoroutine(OperationBlinkSequence()); SetSmallLightsToOperationState(); } else { ResetSmallLightsToDefault(); } } /// /// 运行状态闪烁序列 /// 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); } } /// /// 设置小灯为运行状态 /// private void SetSmallLightsToOperationState() { Color targetColor = GetSmallLightColorByState(currentState); SetSmallLightsColorAndIntensity(targetColor, BREATHING_LIGHT_MAX_INTENSITY); } /// /// 根据当前状态获取小灯颜色 /// private Color GetSmallLightColorByState(LightState state) { return state switch { LightState.Normal => smallLightNormalColor, LightState.Warning => warningColor, LightState.Emergency => emergencyColor, _ => smallLightNormalColor }; } /// /// 重置小灯为默认状态 /// 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; } } } /// /// 更新小灯状态状态 /// private void UpdateSmallLightsStatus() { Color targetColor = smallLightStatus == SmallLightStatus.Normal ? smallLightNormalColor : smallLightErrorColor; SetSmallLightsColorAndIntensity(targetColor, BREATHING_LIGHT_MAX_INTENSITY); } /// /// 小灯闪烁协程 /// private IEnumerator SmallLightsBlinkRoutine() { while (true) { if (!isSystemOn) { TurnOffAllSmallLights(); } else if (smallLightState == SmallLightState.Default) { ResetSmallLightsToDefault(); } yield return new WaitForSeconds(smallLightBlinkInterval); } } #endregion #region 私有方法 - 环境灯相关 /// /// 环境灯闪烁协程 /// 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); } } /// /// 根据状态获取环境灯强度 /// private float GetEnvironmentIntensityByState(LightState state) { return state switch { LightState.Normal => normalEnvironmentIntensity, LightState.Warning => warningEnvironmentIntensity, LightState.Emergency => emergencyEnvironmentIntensity, _ => normalEnvironmentIntensity }; } #endregion #region 私有方法 - 系统启动序列 /// /// 系统启动序列 /// 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); } /// /// ECG波形闪烁序列 /// 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); } /// /// 面板灯启动序列 /// 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); } /// /// 小灯自检序列 /// 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 } }