fix(memory): 优化彩色褪色扫光并复位拉杆视觉

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-21 17:41:46 +08:00
co-authored by Cursor
parent c7c0e96110
commit 046b1a9efb
3 changed files with 146 additions and 28 deletions
@@ -15,6 +15,9 @@ namespace AibisDream.FixSystem
{
private const string MemorySpritePath = "Sprite/Memory/{0}.png";
private const float FadeMaterialStartValue = -15f;
// ColorFadeOut 专用:从溶解刚要开始的位置起 tween,去掉 -15→-8 的空转,让整段时长都是可见的褪色。
private const float ColorFadeStartValue = -8.5f;
private const float ColorFadeDuration = 4f;
private const float DefaultFadeDuration = 1f;
private const float MemoryFinishSnowDuration = 0.1f;
private const float SearchStartDelay = 1f;
@@ -124,9 +127,8 @@ namespace AibisDream.FixSystem
private void PrepareMemoryView()
{
EnsurePunchTapeSlotReference();
PunchTapeManager.Instance.OpenFavoritesPanel();
playBackground.gameObject.SetActive(false);
playBackground.alpha = 0;
ResolvePunchTapeManager()?.OpenFavoritesPanel();
SetPlayBackgroundVisible(false, 0f);
StartStandbyOverlay();
}
@@ -139,7 +141,7 @@ namespace AibisDream.FixSystem
isPlayingFaderSound = false;
}
PunchTapeManager.Instance.CloseFavoritesPanel();
ResolvePunchTapeManager()?.CloseFavoritesPanel();
CloseMemoryView();
// 离开视图时的逻辑
Debug.Log("MemoryView exited.");
@@ -156,6 +158,31 @@ namespace AibisDream.FixSystem
}
}
private PunchTapeManager ResolvePunchTapeManager()
{
var manager = PunchTapeManager.Resolve();
if (manager == null)
{
Debug.LogError(
"[MemoryProcess] 未找到 PunchTapeManager。请确认当前 Fix 场景中存在 PunchTapeCanvas。",
this);
}
return manager;
}
private void SetPlayBackgroundVisible(bool active, float alpha)
{
if (playBackground == null)
{
Debug.LogWarning("[MemoryProcess] playBackground 未配置。", this);
return;
}
playBackground.gameObject.SetActive(active);
playBackground.alpha = alpha;
}
private void Awake()
{
InitSystem();
@@ -293,8 +320,9 @@ namespace AibisDream.FixSystem
}
/// <summary>
/// 单条记忆播放结束后的复位:不调用 <see cref="MemorySlider.Init"/>(避免再次锁条并触发打开 Timeline),
/// 仅禁用拖动;完整 <see cref="MemorySlider.LockSlider"/> 仅在退出 <see cref="MemoryCue"/> 时 <see cref="OnExit"/> 执行。
/// 单条记忆播放结束后的复位:不调用 <see cref="MemorySlider.Init"/> / <see cref="MemorySlider.LockSlider"/>
/// (避免收起 Timeline),仅禁用拖动并把拉杆视觉回到默认位置;
/// 完整 <see cref="MemorySlider.LockSlider"/> 仅在退出记忆模块时 <see cref="OnExit"/> 执行。
/// </summary>
private void ResetAfterMemoryFinished()
{
@@ -307,9 +335,15 @@ namespace AibisDream.FixSystem
}
if (frequencySlider != null)
{
frequencySlider.SetInteractable(false);
frequencySlider.ResetVisualToDefault();
}
if (claritySlider != null)
{
claritySlider.SetInteractable(false);
claritySlider.ResetVisualToDefault();
}
ResetPresentationState();
}
@@ -324,23 +358,24 @@ namespace AibisDream.FixSystem
_activePunchTape = null;
StartStandbyOverlay();
playBackground.gameObject.SetActive(false);
playBackground.alpha = 0;
SetPlayBackgroundVisible(false, 0f);
}
[YarnCommand("MemoryFinished")]
public IEnumerator MemoryFinished()
{
yield return playBackground.DOFade(0f, DefaultFadeDuration).WaitForCompletion();
playBackground.gameObject.SetActive(false);
if (playBackground != null)
{
yield return playBackground.DOFade(0f, DefaultFadeDuration).WaitForCompletion();
playBackground.gameObject.SetActive(false);
}
// 短闪雪花再回待机,避免记忆画面硬切
SetMemoryColor(Color.black);
ShowSearchOverlay();
yield return new WaitForSeconds(MemoryFinishSnowDuration);
PunchTapeManager.Instance.OpenFavoritesPanel();
ResolvePunchTapeManager()?.OpenFavoritesPanel();
ResetAfterMemoryFinished();
EnsurePunchTapeSlotReference();
@@ -356,11 +391,11 @@ namespace AibisDream.FixSystem
{
if (fadeMaterial == null) yield break;
SetFloatIfExists(DirectionalDistortionFadeId, FadeMaterialStartValue);
SetFloatIfExists(DirectionalDistortionFadeId, ColorFadeStartValue);
DG.Tweening.Sequence sequence = DOTween.Sequence();
AppendMaterialFloatTween(sequence, fadeMaterial, 0f, DirectionalDistortionFadeProperty, 3f);
AppendMaterialFloatTween(sequence, fadeMaterial, 0f, DirectionalDistortionFadeProperty, ColorFadeDuration);
if (runtimeNoColorMemoryMaterial != null && runtimeNoColorMemoryMaterial != fadeMaterial)
AppendMaterialFloatTween(sequence, runtimeNoColorMemoryMaterial, 0f, DirectionalDistortionFadeProperty, 3f);
AppendMaterialFloatTween(sequence, runtimeNoColorMemoryMaterial, 0f, DirectionalDistortionFadeProperty, ColorFadeDuration);
Tween tween = sequence;
yield return tween.WaitForCompletion();
}
@@ -369,7 +404,8 @@ namespace AibisDream.FixSystem
public IEnumerator PlayMemory(bool useYarn = false, string memName = "")
{
SetMemoryColor(Color.white);
PunchTapeManager.Instance.CloseFavoritesPanel();
var punchTapeManager = ResolvePunchTapeManager();
punchTapeManager?.CloseFavoritesPanel();
if (useYarn)
{
@@ -395,14 +431,15 @@ namespace AibisDream.FixSystem
}
}
playBackground.gameObject.SetActive(true);
playBackground.alpha = 0;
SetPlayBackgroundVisible(true, 0f);
AudioManager.Instance.PlaySfx("event:/ActionFB/mem_play");
yield return playBackground.DOFade(1f, DefaultFadeDuration).WaitForCompletion();
if (playBackground != null)
yield return playBackground.DOFade(1f, DefaultFadeDuration).WaitForCompletion();
if (!useYarn)
{
if (!PunchTapeManager.Instance.TryGetDefinition(punchTapeSlot.punchTape, out var definition))
if (punchTapeManager == null ||
!punchTapeManager.TryGetDefinition(punchTapeSlot.punchTape, out var definition))
yield break;
DialogController.Instance.StartDialogNode(definition.DialogNode);
@@ -419,7 +456,8 @@ namespace AibisDream.FixSystem
frequencySlider.TargetValue = GetRandomSearchTarget(frequencySlider);
claritySlider.TargetValue = GetRandomSearchTarget(claritySlider);
PunchTapeManager.Instance.CloseFavoritesPanel();
var punchTapeManager = ResolvePunchTapeManager();
punchTapeManager?.CloseFavoritesPanel();
if (punchTape == null)
{
@@ -430,7 +468,8 @@ namespace AibisDream.FixSystem
_activePunchTape = punchTape;
if (!PunchTapeManager.Instance.TryGetDefinition(_activePunchTape, out var definition))
if (punchTapeManager == null ||
!punchTapeManager.TryGetDefinition(_activePunchTape, out var definition))
{
StartStandbyOverlay();
yield break;
@@ -63,6 +63,22 @@ namespace AibisDream.FixSystem
_volume.weight = 0f;
}
/// <summary>
/// 将拉杆视觉复位到默认位置并清零调谐输出(不播 Timeline、不触发搜索判定)。
/// 用于记忆播放结束后回到待机界面。
/// </summary>
public void ResetVisualToDefault()
{
IsFound = false;
if (slider == null)
slider = GetComponent<Slider>();
slider.SetValueWithoutNotify(defaultValue);
if (_volume != null && driveVolume)
_volume.weight = 0f;
OnTuningChanged?.Invoke(0f);
}
/// <summary>
/// 新一轮搜索前复位滑条与 IsFound(不播 Timeline、不改变视觉锁状态)。
/// 需先设置好 <see cref="TargetValue"/>。