diff --git a/Assets/Scripts/FixSystem/Memory/MemorySlider.cs b/Assets/Scripts/FixSystem/Memory/MemorySlider.cs index 20e1bbe4c..146c629be 100644 --- a/Assets/Scripts/FixSystem/Memory/MemorySlider.cs +++ b/Assets/Scripts/FixSystem/Memory/MemorySlider.cs @@ -13,6 +13,8 @@ namespace AibisDream.FixSystem [SerializeField] private float defaultValue = 0f; [SerializeField] private float sliderMaxValue = 6f; [SerializeField] private float lockThreshold = 0.08f; + [SerializeField] private float nearThreshold = 0.24f; + [SerializeField, Range(0f, 1f)] private float unresolvedVisualFloor = 0.12f; [SerializeField] private TimelineAsset openAsset; [SerializeField] private TimelineAsset closeAsset; @@ -45,7 +47,7 @@ namespace AibisDream.FixSystem slider.onValueChanged.AddListener(HandleValueChanged); slider.maxValue = sliderMaxValue; slider.value = defaultValue; - UpdateVolumeWeight(slider.value); + UpdateTuningOutput(slider.value); isLocked = true; SetInteractable(false); @@ -97,7 +99,7 @@ namespace AibisDream.FixSystem } slider.value = 0f; - UpdateVolumeWeight(0f); + UpdateTuningOutput(0f); PlayTimeline(closeAsset, () => { @@ -108,7 +110,7 @@ namespace AibisDream.FixSystem private void HandleValueChanged(float value) { - float t = UpdateVolumeWeight(value); + float t = UpdateTuningOutput(value); bool wasFound = IsFound; IsFound = t < lockThreshold; @@ -119,19 +121,44 @@ namespace AibisDream.FixSystem OnLost?.Invoke(); } - private float UpdateVolumeWeight(float value) + private float UpdateTuningOutput(float value) + { + float t = GetNormalizedDistance(value); + float visualStrength = GetVisualStrength(t); + + if (_volume != null && driveVolume) + _volume.weight = Mathf.Lerp(0, 1, visualStrength); + + OnTuningChanged?.Invoke(visualStrength); + + return t; + } + + private float GetNormalizedDistance(float value) { float distance = Mathf.Abs(value - TargetValue); float maxDistance = Mathf.Max( Mathf.Abs(slider.maxValue - TargetValue), Mathf.Abs(slider.minValue - TargetValue) ); - float t = Mathf.Clamp01(distance / maxDistance); - if (_volume != null && driveVolume) - _volume.weight = Mathf.Lerp(0, 1, t); + return Mathf.Clamp01(distance / Mathf.Max(0.0001f, maxDistance)); + } - OnTuningChanged?.Invoke(t); + private float GetVisualStrength(float t) + { + float lockBand = Mathf.Clamp01(lockThreshold); + float nearBand = Mathf.Clamp(Mathf.Max(nearThreshold, lockBand + 0.001f), lockBand + 0.001f, 1f); + + if (t <= lockBand) + return 0f; + + if (t < nearBand) + { + float nearProgress = Mathf.InverseLerp(lockBand, nearBand, t); + float easedProgress = Mathf.SmoothStep(0f, 1f, nearProgress); + return Mathf.Lerp(unresolvedVisualFloor, nearBand, easedProgress); + } return t; }