fix(dialog): 修复快进时后处理渐变回写
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AibisDream.Framework;
|
||||
using AibisDream.UI;
|
||||
using UnityEngine;
|
||||
@@ -11,6 +12,10 @@ namespace AibisDream
|
||||
{
|
||||
public static class BaseYarnCommand
|
||||
{
|
||||
private static readonly Dictionary<int, long> ActiveVolumeWeightTweens = new();
|
||||
private static readonly Dictionary<int, long> ActiveVolumeBrightnessTweens = new();
|
||||
private static long _nextVolumeTweenToken;
|
||||
|
||||
#region 命令名
|
||||
|
||||
[YarnCommand("NextYarn")]
|
||||
@@ -54,6 +59,7 @@ namespace AibisDream
|
||||
return;
|
||||
}
|
||||
|
||||
CancelVolumeTween(volume, ActiveVolumeWeightTweens);
|
||||
volume.weight = Mathf.Clamp01(weight);
|
||||
}
|
||||
|
||||
@@ -69,23 +75,14 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
targetWeight = Mathf.Clamp01(targetWeight);
|
||||
if (duration <= 0f)
|
||||
{
|
||||
volume.weight = targetWeight;
|
||||
yield break;
|
||||
}
|
||||
|
||||
var startWeight = volume.weight;
|
||||
var elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
var progress = Mathf.Clamp01(elapsed / duration);
|
||||
volume.weight = Mathf.Lerp(startWeight, targetWeight, EaseInOutSine(progress));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
volume.weight = targetWeight;
|
||||
yield return TweenVolumeFloat(
|
||||
volume,
|
||||
ActiveVolumeWeightTweens,
|
||||
() => volume.weight,
|
||||
value => volume.weight = value,
|
||||
targetWeight,
|
||||
duration,
|
||||
EaseInOutSine);
|
||||
}
|
||||
|
||||
[YarnCommand("tween_volume_weight_async")]
|
||||
@@ -103,28 +100,32 @@ namespace AibisDream
|
||||
[YarnCommand("set_volume_brightness")]
|
||||
public static void SetVolumeBrightness(string volumeName, float brightness)
|
||||
{
|
||||
if (!TryGetVolumeAdjustments(volumeName, out _, out var adjustments))
|
||||
if (!TryGetVolumeAdjustments(volumeName, out var volume, out var adjustments))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CancelVolumeTween(volume, ActiveVolumeBrightnessTweens);
|
||||
adjustments.m_Brightness.value = Mathf.Clamp(brightness, -1f, 1f);
|
||||
}
|
||||
|
||||
[YarnCommand("tween_volume_brightness")]
|
||||
public static IEnumerator TweenVolumeBrightness(string volumeName, float targetBrightness, float duration)
|
||||
{
|
||||
if (!TryGetVolumeAdjustments(volumeName, out _, out var adjustments))
|
||||
if (!TryGetVolumeAdjustments(volumeName, out var volume, out var adjustments))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
targetBrightness = Mathf.Clamp(targetBrightness, -1f, 1f);
|
||||
yield return TweenUnscaledFloat(
|
||||
yield return TweenVolumeFloat(
|
||||
volume,
|
||||
ActiveVolumeBrightnessTweens,
|
||||
() => adjustments.m_Brightness.value,
|
||||
value => adjustments.m_Brightness.value = value,
|
||||
targetBrightness,
|
||||
duration);
|
||||
duration,
|
||||
SmootherStep);
|
||||
}
|
||||
|
||||
[YarnCommand("tween_volume_brightness_async")]
|
||||
@@ -153,12 +154,12 @@ namespace AibisDream
|
||||
|
||||
// Bloom 先扩散;等 Bloom 完全起来后,才用曝光把剩余暗部推到纯白。
|
||||
adjustments.m_Brightness.value = 0f;
|
||||
yield return TweenUnscaledFloat(
|
||||
yield return TweenFloat(
|
||||
() => volume.weight,
|
||||
value => volume.weight = value,
|
||||
1f,
|
||||
bloomDuration);
|
||||
yield return TweenUnscaledFloat(
|
||||
yield return TweenFloat(
|
||||
() => adjustments.m_Brightness.value,
|
||||
value => adjustments.m_Brightness.value = value,
|
||||
1f,
|
||||
@@ -177,12 +178,12 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
// 先从纯白恢复画面层次,再逐渐收掉仍然存在的 Bloom。
|
||||
yield return TweenUnscaledFloat(
|
||||
yield return TweenFloat(
|
||||
() => adjustments.m_Brightness.value,
|
||||
value => adjustments.m_Brightness.value = value,
|
||||
0f,
|
||||
exposureDuration);
|
||||
yield return TweenUnscaledFloat(
|
||||
yield return TweenFloat(
|
||||
() => volume.weight,
|
||||
value => volume.weight = value,
|
||||
0f,
|
||||
@@ -217,7 +218,7 @@ namespace AibisDream
|
||||
return true;
|
||||
}
|
||||
|
||||
private static IEnumerator TweenUnscaledFloat(
|
||||
private static IEnumerator TweenFloat(
|
||||
Func<float> getter,
|
||||
Action<float> setter,
|
||||
float target,
|
||||
@@ -233,7 +234,8 @@ namespace AibisDream
|
||||
var elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
// 与 Yarn 的 <<wait>> 使用同一时间域,让快进同步加速后处理演出。
|
||||
elapsed += Time.deltaTime;
|
||||
var progress = Mathf.Clamp01(elapsed / duration);
|
||||
setter(Mathf.Lerp(start, target, SmootherStep(progress)));
|
||||
yield return null;
|
||||
@@ -242,6 +244,69 @@ namespace AibisDream
|
||||
setter(target);
|
||||
}
|
||||
|
||||
private static IEnumerator TweenVolumeFloat(
|
||||
Volume volume,
|
||||
Dictionary<int, long> activeTweens,
|
||||
Func<float> getter,
|
||||
Action<float> setter,
|
||||
float target,
|
||||
float duration,
|
||||
Func<float, float> easing)
|
||||
{
|
||||
var volumeId = volume.GetInstanceID();
|
||||
var token = ++_nextVolumeTweenToken;
|
||||
activeTweens[volumeId] = token;
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
if (IsCurrentVolumeTween(activeTweens, volumeId, token))
|
||||
setter(target);
|
||||
CompleteVolumeTween(activeTweens, volumeId, token);
|
||||
yield break;
|
||||
}
|
||||
|
||||
var start = getter();
|
||||
var elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
if (volume == null || !IsCurrentVolumeTween(activeTweens, volumeId, token))
|
||||
yield break;
|
||||
|
||||
// 与 Yarn 的 <<wait>> 使用同一时间域,让快进同步加速后处理演出。
|
||||
elapsed += Time.deltaTime;
|
||||
var progress = Mathf.Clamp01(elapsed / duration);
|
||||
setter(Mathf.Lerp(start, target, easing(progress)));
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (volume != null && IsCurrentVolumeTween(activeTweens, volumeId, token))
|
||||
setter(target);
|
||||
CompleteVolumeTween(activeTweens, volumeId, token);
|
||||
}
|
||||
|
||||
private static void CancelVolumeTween(Volume volume, Dictionary<int, long> activeTweens)
|
||||
{
|
||||
if (volume != null)
|
||||
activeTweens.Remove(volume.GetInstanceID());
|
||||
}
|
||||
|
||||
private static bool IsCurrentVolumeTween(
|
||||
Dictionary<int, long> activeTweens,
|
||||
int volumeId,
|
||||
long token)
|
||||
{
|
||||
return activeTweens.TryGetValue(volumeId, out var activeToken) && activeToken == token;
|
||||
}
|
||||
|
||||
private static void CompleteVolumeTween(
|
||||
Dictionary<int, long> activeTweens,
|
||||
int volumeId,
|
||||
long token)
|
||||
{
|
||||
if (IsCurrentVolumeTween(activeTweens, volumeId, token))
|
||||
activeTweens.Remove(volumeId);
|
||||
}
|
||||
|
||||
private static float EaseInOutSine(float progress)
|
||||
{
|
||||
progress = Mathf.Clamp01(progress);
|
||||
|
||||
Reference in New Issue
Block a user