From 2ac0b4695dde65aaa5103216bf9075ef71634bff Mon Sep 17 00:00:00 2001 From: bottlefish <781230111@qq.com> Date: Tue, 21 Jul 2026 01:18:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(fix-panel):=20Warning=E5=9B=9E=E8=90=BD?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=97=AA=E7=83=81=E6=B7=A1=E5=87=BA=E5=B9=B6?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=E7=AD=89=E5=BE=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../Screen System/Core/FixPanelLight.cs | 178 +++++++++++++++++- Assets/Yarn/FP/FP_Prologue/Stage2-5_切割.yarn | 3 + 2 files changed, 172 insertions(+), 9 deletions(-) diff --git a/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelLight.cs b/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelLight.cs index a5e8b1453..78e18b827 100644 --- a/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelLight.cs +++ b/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelLight.cs @@ -73,6 +73,16 @@ namespace AibisDream.FixSystem [SerializeField] private float emergencyOutroDuration = 0.18f; [SerializeField, Range(0f, 1f)] private float emergencyIntroDipIntensityScale = 0.55f; + [Header("普通状态转场")] + [Tooltip("Normal→Warning 等非紧急切换的过渡时长")] + [SerializeField] private float softStateTransitionDuration = 0.55f; + [Tooltip("Warning→Normal:先闪几次再淡出,让镇静回落更明显")] + [SerializeField, Min(1)] private int warningSettleBlinkCount = 2; + [SerializeField, Min(0.02f)] private float warningSettleBlinkOnDuration = 0.14f; + [SerializeField, Min(0.02f)] private float warningSettleBlinkOffDuration = 0.12f; + [SerializeField, Min(0.1f)] private float warningSettleFadeDuration = 1.15f; + [SerializeField, Range(0f, 1f)] private float warningSettleBlinkDipScale = 0.28f; + private Tween alarmTween; private Tween lightStateTransitionTween; private LightState currentState = LightState.Normal; @@ -240,7 +250,7 @@ namespace AibisDream.FixSystem #region 光照系统 - 状态更新方法 /// - /// 根据紧急状态的进入/退出选择短转场,其他状态保持即时切换。 + /// Emergency 用专属进出场;Warning→Normal 闪两下再淡出;其余短过渡。 /// private void TransitionLightsState(LightState previousState, LightState newState) { @@ -261,10 +271,13 @@ namespace AibisDream.FixSystem { PlayEmergencyOutro(stateConfig); } + else if (previousState == LightState.Warning && newState == LightState.Normal) + { + PlayWarningSettleOutro(stateConfig); + } else { - UpdateAlarmLight(stateConfig); - UpdateEnvironmentLight(stateConfig); + PlaySoftStateTransition(stateConfig); } } @@ -336,21 +349,118 @@ namespace AibisDream.FixSystem private void PlayEmergencyOutro((bool alarmEnabled, Color alarmColor, float alarmMaxIntensity, float alarmBlinkDuration, Color envColor, float envIntensity) config) { - float duration = Mathf.Max(0.01f, emergencyOutroDuration); + PlaySoftStateTransition(config, emergencyOutroDuration); + } + + /// + /// Warning→Normal:警报/红调先明显闪两下,再较慢落到正常光。 + /// + private void PlayWarningSettleOutro( + (bool alarmEnabled, Color alarmColor, float alarmMaxIntensity, + float alarmBlinkDuration, Color envColor, float envIntensity) config) + { + var warningConfig = GetStateConfig(LightState.Warning); + float blinkOn = Mathf.Max(0.02f, warningSettleBlinkOnDuration); + float blinkOff = Mathf.Max(0.02f, warningSettleBlinkOffDuration); + float fadeDuration = Mathf.Max(0.1f, warningSettleFadeDuration); + int blinkCount = Mathf.Max(1, warningSettleBlinkCount); + + float startEnvIntensity = environmentLight != null + ? environmentLight.intensity + : warningConfig.envIntensity; + Color startEnvColor = environmentLight != null + ? environmentLight.color + : warningConfig.envColor; + float startAlarmIntensity = alarmLight != null + ? Mathf.Max(alarmLight.intensity, warningConfig.alarmMaxIntensity * 0.65f) + : warningConfig.alarmMaxIntensity; + + if (alarmLight != null) + { + alarmLight.color = warningConfig.alarmColor; + alarmLight.intensity = startAlarmIntensity; + } + + Color blinkDipColor = Color.Lerp(startEnvColor, config.envColor, 0.55f); + float blinkDipIntensity = startEnvIntensity * Mathf.Clamp01(warningSettleBlinkDipScale); DG.Tweening.Sequence sequence = DOTween.Sequence(); + for (int i = 0; i < blinkCount; i++) + { + // 灭:警报关 + 红调明显压一下 + if (alarmLight != null) + { + sequence.Append(DOTween.To( + () => alarmLight.intensity, + value => alarmLight.intensity = value, + 0f, + blinkOff).SetEase(Ease.InQuad)); + } + else + { + sequence.AppendInterval(blinkOff); + } + + if (environmentLight != null) + { + sequence.Join(DOTween.To( + () => environmentLight.intensity, + value => environmentLight.intensity = value, + blinkDipIntensity, + blinkOff).SetEase(Ease.InQuad)); + sequence.Join(DOTween.To( + () => environmentLight.color, + value => environmentLight.color = value, + blinkDipColor, + blinkOff).SetEase(Ease.InQuad)); + } + + // 亮:警报弹回 + 红调回满(第二下更像“挣扎熄灭”) + if (alarmLight != null) + { + sequence.Append(DOTween.To( + () => alarmLight.intensity, + value => alarmLight.intensity = value, + startAlarmIntensity, + blinkOn).SetEase(Ease.OutQuad)); + } + else + { + sequence.AppendInterval(blinkOn); + } + + if (environmentLight != null) + { + sequence.Join(DOTween.To( + () => environmentLight.intensity, + value => environmentLight.intensity = value, + startEnvIntensity, + blinkOn).SetEase(Ease.OutQuad)); + sequence.Join(DOTween.To( + () => environmentLight.color, + value => environmentLight.color = value, + startEnvColor, + blinkOn).SetEase(Ease.OutQuad)); + } + } + + // 末段:红调与警报一起慢淡到 Normal if (environmentLight != null) { - sequence.Join(DOTween.To( + sequence.Append(DOTween.To( () => environmentLight.intensity, value => environmentLight.intensity = value, config.envIntensity, - duration).SetEase(Ease.OutQuad)); + fadeDuration).SetEase(Ease.InOutSine)); sequence.Join(DOTween.To( () => environmentLight.color, value => environmentLight.color = value, config.envColor, - duration).SetEase(Ease.OutQuad)); + fadeDuration).SetEase(Ease.InOutSine)); + } + else + { + sequence.AppendInterval(fadeDuration); } if (alarmLight != null) @@ -359,7 +469,57 @@ namespace AibisDream.FixSystem () => alarmLight.intensity, value => alarmLight.intensity = value, 0f, - duration).SetEase(Ease.OutQuad)); + fadeDuration).SetEase(Ease.InQuad)); + } + + LightState targetState = currentState; + lightStateTransitionTween = sequence.OnComplete(() => + { + lightStateTransitionTween = null; + if (currentState != targetState) return; + StopAlarmLight(); + }); + } + + /// + /// Warning ↔ Normal 等普通切换:环境色/强度与警报灯一起短过渡。 + /// + private void PlaySoftStateTransition( + (bool alarmEnabled, Color alarmColor, float alarmMaxIntensity, + float alarmBlinkDuration, Color envColor, float envIntensity) config, + float? overrideDuration = null) + { + float duration = Mathf.Max(0.01f, overrideDuration ?? softStateTransitionDuration); + DG.Tweening.Sequence sequence = DOTween.Sequence(); + + if (environmentLight != null) + { + sequence.Join(DOTween.To( + () => environmentLight.intensity, + value => environmentLight.intensity = value, + config.envIntensity, + duration).SetEase(Ease.InOutSine)); + sequence.Join(DOTween.To( + () => environmentLight.color, + value => environmentLight.color = value, + config.envColor, + duration).SetEase(Ease.InOutSine)); + } + + if (alarmLight != null) + { + float targetAlarmIntensity = config.alarmEnabled ? config.alarmMaxIntensity : 0f; + alarmLight.color = Color.Lerp(alarmLight.color, config.alarmColor, 0.35f); + sequence.Join(DOTween.To( + () => alarmLight.color, + value => alarmLight.color = value, + config.alarmColor, + duration).SetEase(Ease.InOutSine)); + sequence.Join(DOTween.To( + () => alarmLight.intensity, + value => alarmLight.intensity = value, + targetAlarmIntensity, + duration).SetEase(Ease.InOutSine)); } if (environmentLight == null && alarmLight == null) @@ -375,7 +535,7 @@ namespace AibisDream.FixSystem if (config.alarmEnabled) { - StartAlarmLightBlink(config); + StartAlarmLightBlink(config, startLit: true); } else { diff --git a/Assets/Yarn/FP/FP_Prologue/Stage2-5_切割.yarn b/Assets/Yarn/FP/FP_Prologue/Stage2-5_切割.yarn index 411a27d55..56f3928b7 100644 --- a/Assets/Yarn/FP/FP_Prologue/Stage2-5_切割.yarn +++ b/Assets/Yarn/FP/FP_Prologue/Stage2-5_切割.yarn @@ -261,10 +261,13 @@ gts??: 医生…我好困…… #line:0fc221c me: 很快就好了。 #line:0b41425 <> <> +// 等 Warning 闪两下 + 慢淡出落稳(约 1.7s),再接镇静台词 +<> EmoModule: 指令执行完成!正在刷新... #line:05ce8bb gts?: 它消失了,医生。谢谢你。 Error: 原型泄漏:35.2% #line:09ef3b8 <> +<> <> // 情绪/逻辑/记忆进入损坏状态:文字闪烁+间歇火花 <>