Merge branch 'develop' into feature/开发模式
This commit is contained in:
@@ -522,6 +522,47 @@ namespace AibisDream
|
||||
yield return SpriteShowcase.Instance.ShowLargeObj(picName, duration);
|
||||
}
|
||||
|
||||
[YarnCommand("show_large_sprite_animation")]
|
||||
public static IEnumerator ShowLargeSpriteAnimation(
|
||||
string picNamePrefix,
|
||||
int frameCount,
|
||||
float secondsPerFrame = 0.2f,
|
||||
float duration = 1f)
|
||||
{
|
||||
yield return SpriteShowcase.Instance.ShowLargeSpriteAnimation(
|
||||
picNamePrefix,
|
||||
frameCount,
|
||||
secondsPerFrame,
|
||||
duration);
|
||||
}
|
||||
|
||||
[YarnCommand("set_large_sprite_blur")]
|
||||
public static void SetLargeSpriteBlur(float amount, float blurSize = 0.012f)
|
||||
{
|
||||
SpriteShowcase.Instance.SetLargeSpriteBlur(amount, blurSize);
|
||||
}
|
||||
|
||||
[YarnCommand("tween_large_sprite_blur")]
|
||||
public static IEnumerator TweenLargeSpriteBlur(
|
||||
float targetAmount,
|
||||
float duration,
|
||||
float blurSize = 0.012f)
|
||||
{
|
||||
yield return SpriteShowcase.Instance.TweenLargeSpriteBlur(targetAmount, duration, blurSize);
|
||||
}
|
||||
|
||||
[YarnCommand("tween_large_sprite_blur_async")]
|
||||
public static void TweenLargeSpriteBlurAsync(
|
||||
float targetAmount,
|
||||
float duration,
|
||||
float blurSize = 0.012f)
|
||||
{
|
||||
if (DialogController.Instance == null) return;
|
||||
|
||||
DialogController.Instance.StartCoroutine(
|
||||
SpriteShowcase.Instance.TweenLargeSpriteBlur(targetAmount, duration, blurSize));
|
||||
}
|
||||
|
||||
[YarnCommand("hide_large_sprite")]
|
||||
public static IEnumerator HideLargeSprite(float duration = 1)
|
||||
{
|
||||
|
||||
@@ -22,8 +22,8 @@ public class HeatMapController : MonoBehaviour
|
||||
public Transform imageToRotate; // 需要旋转的Image
|
||||
[SerializeField, Min(0f)] private float fanStopDuration = 0.15f;
|
||||
[Header("低温背景")]
|
||||
[SerializeField] private Color coldBaseColor = new Color(0.015f, 0.075f, 0.16f, 1f);
|
||||
[SerializeField] private Color coldHighlightColor = new Color(0.02f, 0.27f, 0.48f, 1f);
|
||||
[SerializeField] private Color coldBaseColor = new Color(0.005f, 0.02f, 0.55f, 1f);
|
||||
[SerializeField] private Color coldHighlightColor = new Color(0f, 0.3f, 1f, 1f);
|
||||
[SerializeField, Min(0.01f)] private float coldNoiseScale = 1.8f;
|
||||
[SerializeField, Range(0f, 1f)] private float coldNoiseStrength = 0.45f;
|
||||
public Vector3 inPos; // Heatmap进入位置
|
||||
@@ -244,7 +244,7 @@ public class HeatMapController : MonoBehaviour
|
||||
public void SetDataToMaterial()
|
||||
{
|
||||
// 逻辑温度 0~2 → shader 侧发热强度;各段端点连续,避免跨档跳变。
|
||||
// t=0 冷态压低,接近「看不见」;t=1/2 保持原有发热观感。
|
||||
// 保持原有温度映射,冷色替换只由 shader 处理。
|
||||
if (tempture <= 1f)
|
||||
{
|
||||
float t = Mathf.Clamp01(tempture);
|
||||
@@ -256,7 +256,7 @@ public class HeatMapController : MonoBehaviour
|
||||
{
|
||||
float t = Mathf.Clamp01(tempture - 1f);
|
||||
uftempture = Mathf.Lerp(2.8f, 3.2f, t);
|
||||
modulesTempture = Mathf.Lerp(1.6f, 2.3f, t); // 原 1.8 起点与上一段不连续
|
||||
modulesTempture = Mathf.Lerp(1.6f, 2.3f, t);
|
||||
backtemture = Mathf.Lerp(2.25f, 3.4f, t);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ Shader "Unlit/HeatTest"
|
||||
_Speaktexture ("_Speaktexture", 2D) = "white" {}
|
||||
_headtexture ("_headtexture", 2D) = "white" {}
|
||||
_Temtupre("_Temtupre", float) = 0 // 世界空间中的中心
|
||||
_ColdBaseColor ("Cold Base Color", Color) = (0.015, 0.075, 0.16, 1)
|
||||
_ColdHighlightColor ("Cold Highlight Color", Color) = (0.02, 0.27, 0.48, 1)
|
||||
_ColdBaseColor ("Cold Base Color", Color) = (0.005, 0.02, 0.55, 1)
|
||||
_ColdHighlightColor ("Cold Highlight Color", Color) = (0, 0.3, 1, 1)
|
||||
_ColdNoiseScale ("Cold Noise Scale", Float) = 1.8
|
||||
_ColdNoiseStrength ("Cold Noise Strength", Range(0, 1)) = 0.45
|
||||
}
|
||||
@@ -150,7 +150,8 @@ fixed4 frag (v2f i) : SV_Target
|
||||
float2 coldNoiseUV = worldPos.xy + float2(_Time.y * 0.012, -_Time.y * 0.009);
|
||||
float coldNoise = Unity_SimpleNoise(coldNoiseUV, _ColdNoiseScale);
|
||||
float coldVariation = saturate(0.18 + coldNoise * _ColdNoiseStrength);
|
||||
fixed4 col = lerp(_ColdBaseColor, _ColdHighlightColor, coldVariation);
|
||||
fixed4 coldColor = lerp(_ColdBaseColor, _ColdHighlightColor, coldVariation);
|
||||
fixed4 col = coldColor;
|
||||
bool isFind = false;
|
||||
|
||||
|
||||
@@ -184,7 +185,10 @@ fixed4 frag (v2f i) : SV_Target
|
||||
|
||||
|
||||
fixed4 rampColor = tex2D(_RampTexture, float2(alpha, 0));
|
||||
col = rampColor;
|
||||
// 保留原有色带映射,只把接近黑色的冷端替换为蓝色。
|
||||
float brightestChannel = max(rampColor.r, max(rampColor.g, rampColor.b));
|
||||
float blackMask = 1.0 - smoothstep(0.035, 0.12, brightestChannel);
|
||||
col = lerp(rampColor, coldColor, blackMask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +210,9 @@ fixed4 frag (v2f i) : SV_Target
|
||||
alpha=backalpha;
|
||||
|
||||
fixed4 rampColor = tex2D(_RampTexture, float2(alpha, 0));
|
||||
col = rampColor;
|
||||
float brightestChannel = max(rampColor.r, max(rampColor.g, rampColor.b));
|
||||
float blackMask = 1.0 - smoothstep(0.035, 0.12, brightestChannel);
|
||||
col = lerp(rampColor, coldColor, blackMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,6 +128,8 @@ Material:
|
||||
m_Floats:
|
||||
- _Alpha: 0.992
|
||||
- _Boolean: 0
|
||||
- _ColdNoiseScale: 1.8
|
||||
- _ColdNoiseStrength: 0.45
|
||||
- _ColorHSV_Brightness_1: 1
|
||||
- _ColorHSV_Hue_1: 104
|
||||
- _ColorHSV_Saturation_1: 1
|
||||
@@ -158,6 +160,8 @@ Material:
|
||||
- _Center: {r: -3.77, g: 0.91, b: 0, a: 0}
|
||||
- _CenterScale: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _CircleModuleSize: {r: 1, g: 1, b: 0, a: 0}
|
||||
- _ColdBaseColor: {r: 0.005, g: 0.02, b: 0.55, a: 1}
|
||||
- _ColdHighlightColor: {r: 0, g: 0.3, b: 1, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _ColorX: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Flip: {r: 1, g: 1, b: 1, a: 1}
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace AibisDream
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator StartCutting(BodyModule targetModule)
|
||||
public IEnumerator StartCutting(BodyModule targetModule, bool flickerCutTextOnEnter = false)
|
||||
{
|
||||
// 检查参数
|
||||
if (targetModule == null)
|
||||
@@ -121,6 +121,13 @@ namespace AibisDream
|
||||
|
||||
// 停止之前的切割
|
||||
StopCutting();
|
||||
|
||||
// StopCutting 会将 Cut Text 恢复为可见,因此需要在调用后同步进入状态。
|
||||
_targetModule.SetCutTextVisible(flickerCutTextOnEnter);
|
||||
if (flickerCutTextOnEnter)
|
||||
{
|
||||
_targetModule.StartCutTextFlicker();
|
||||
}
|
||||
|
||||
// 设置切割模式
|
||||
isCuttingMode = true;
|
||||
@@ -322,4 +329,4 @@ namespace AibisDream
|
||||
_targetSpriteRenderer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace AibisDream.FixSystem
|
||||
yield return UIManager.Instance.GetPanel<ScreenTransitionPanel>().FadeInAsync(0.1f);
|
||||
yield return CameraKit.Instance.SwitchCamera(CameraEnum.CutMemoryDeep);
|
||||
yield return UIManager.Instance.GetPanel<ScreenTransitionPanel>().FadeOutAsync(0.1f);
|
||||
yield return cuttingManager.StartCutting(bodyModule);
|
||||
yield return cuttingManager.StartCutting(bodyModule, flickerCutTextOnEnter: true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace AibisDream
|
||||
private const string DreamSpritePath = "Sprite/梦境/{0}.png";
|
||||
private const string KiteBaseSuffix = "_底图";
|
||||
private const string KiteMotionSuffix = "_风筝层";
|
||||
private const float ReelMotionSpeedMultiplier = 2f;
|
||||
|
||||
[SerializeField] private SpriteRenderer _spriteRenderer;
|
||||
[SerializeField] private SpriteRenderer _backgroundSpriteRenderer;
|
||||
@@ -37,6 +38,13 @@ namespace AibisDream
|
||||
private Quaternion _largeBaseLocalRotation;
|
||||
private Vector3 _largeBaseLocalScale;
|
||||
private float _largeBaseAlpha;
|
||||
private Material _largeBaseMaterial;
|
||||
private MaterialPropertyBlock _largePropertyBlock;
|
||||
private Coroutine _largeSpriteAnimationCoroutine;
|
||||
|
||||
private static readonly int BlurAmountId = Shader.PropertyToID("_BlurAmount");
|
||||
private static readonly int BlurSizeId = Shader.PropertyToID("_BlurSize");
|
||||
private static readonly int UseSoftFocusId = Shader.PropertyToID("_UseSoftFocus");
|
||||
|
||||
// 通过 activeSelf 判断当前状态
|
||||
private bool IsSmallShowing => _spriteRenderer.gameObject.activeSelf;
|
||||
@@ -89,6 +97,95 @@ namespace AibisDream
|
||||
_largeBaseLocalRotation = tr.localRotation;
|
||||
_largeBaseLocalScale = tr.localScale;
|
||||
_largeBaseAlpha = _largeSpriteRenderer.color.a;
|
||||
_largeBaseMaterial = _largeSpriteRenderer.sharedMaterial;
|
||||
}
|
||||
|
||||
private void StopLargeSpriteAnimation()
|
||||
{
|
||||
if (_largeSpriteAnimationCoroutine == null) return;
|
||||
|
||||
StopCoroutine(_largeSpriteAnimationCoroutine);
|
||||
_largeSpriteAnimationCoroutine = null;
|
||||
}
|
||||
|
||||
private IEnumerator LoopLargeSpriteAnimation(Sprite[] frames, float secondsPerFrame)
|
||||
{
|
||||
var frameIndex = 0;
|
||||
var wait = new WaitForSeconds(Mathf.Max(0.01f, secondsPerFrame));
|
||||
|
||||
while (frames.Length > 0)
|
||||
{
|
||||
if (_largeSpriteRenderer != null)
|
||||
{
|
||||
_largeSpriteRenderer.sprite = frames[frameIndex];
|
||||
}
|
||||
|
||||
frameIndex = (frameIndex + 1) % frames.Length;
|
||||
yield return wait;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyLargeSpriteBlur(float amount, float blurSize)
|
||||
{
|
||||
if (_largeSpriteRenderer == null) return;
|
||||
|
||||
amount = Mathf.Clamp01(amount);
|
||||
if (amount <= 0.001f)
|
||||
{
|
||||
_largeSpriteRenderer.SetPropertyBlock(null);
|
||||
_largeSpriteRenderer.sharedMaterial = _largeBaseMaterial;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_kiteFocusMaterial == null)
|
||||
{
|
||||
Debug.LogWarning("[SpriteShowcase] 未配置全屏图片可用的对焦材质。", this);
|
||||
return;
|
||||
}
|
||||
|
||||
_largeSpriteRenderer.sharedMaterial = _kiteFocusMaterial;
|
||||
_largePropertyBlock ??= new MaterialPropertyBlock();
|
||||
_largeSpriteRenderer.GetPropertyBlock(_largePropertyBlock);
|
||||
_largePropertyBlock.SetFloat(BlurAmountId, amount);
|
||||
_largePropertyBlock.SetFloat(BlurSizeId, Mathf.Max(0f, blurSize));
|
||||
_largePropertyBlock.SetFloat(UseSoftFocusId, 1f);
|
||||
_largeSpriteRenderer.SetPropertyBlock(_largePropertyBlock);
|
||||
}
|
||||
|
||||
public void SetLargeSpriteBlur(float amount, float blurSize = 0.012f)
|
||||
{
|
||||
ApplyLargeSpriteBlur(amount, blurSize);
|
||||
}
|
||||
|
||||
public IEnumerator TweenLargeSpriteBlur(float targetAmount, float duration, float blurSize = 0.012f)
|
||||
{
|
||||
if (_largeSpriteRenderer == null) yield break;
|
||||
|
||||
_largePropertyBlock ??= new MaterialPropertyBlock();
|
||||
_largeSpriteRenderer.GetPropertyBlock(_largePropertyBlock);
|
||||
var startAmount = _largeSpriteRenderer.sharedMaterial == _kiteFocusMaterial
|
||||
? _largePropertyBlock.GetFloat(BlurAmountId)
|
||||
: 0f;
|
||||
targetAmount = Mathf.Clamp01(targetAmount);
|
||||
duration = Mathf.Max(0f, duration);
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ApplyLargeSpriteBlur(targetAmount, blurSize);
|
||||
yield break;
|
||||
}
|
||||
|
||||
var elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
var t = Mathf.Clamp01(elapsed / duration);
|
||||
t = t * t * (3f - 2f * t);
|
||||
ApplyLargeSpriteBlur(Mathf.Lerp(startAmount, targetAmount, t), blurSize);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
ApplyLargeSpriteBlur(targetAmount, blurSize);
|
||||
}
|
||||
|
||||
public IEnumerator AnimateLargePresentation(float scaleMultiplier, float targetAlpha, float duration)
|
||||
@@ -164,6 +261,8 @@ namespace AibisDream
|
||||
{
|
||||
if (_largeSpriteRenderer == null) return;
|
||||
|
||||
StopLargeSpriteAnimation();
|
||||
ApplyLargeSpriteBlur(0f, 0f);
|
||||
ResetLargePresentationImmediate();
|
||||
_largeSpriteRenderer.gameObject.SetActive(false);
|
||||
}
|
||||
@@ -295,6 +394,12 @@ namespace AibisDream
|
||||
: motionProfile.Trim().ToLowerInvariant();
|
||||
}
|
||||
|
||||
private static bool IsReelPic(string picName)
|
||||
{
|
||||
var normalized = NormalizeDreamPicName(picName);
|
||||
return normalized == "D2S轱辘" || normalized == "D2S轱辘没线";
|
||||
}
|
||||
|
||||
private Vector3 BaseOffset(float x, float y)
|
||||
{
|
||||
return _smallBaseLocalPosition + _smallMotionBaseOffset + new Vector3(x, y, 0f);
|
||||
@@ -304,8 +409,9 @@ namespace AibisDream
|
||||
{
|
||||
var normalized = NormalizeDreamPicName(picName);
|
||||
|
||||
// 风筝图已改由风筝 Rig(ShowKite 等)连续驱动,分层底图+遮罩通路仅保留给轱辘特写
|
||||
if (normalized == "D2S轱辘")
|
||||
// 风筝图已改由风筝 Rig(ShowKite 等)连续驱动,分层底图+遮罩通路仅保留给轱辘特写。
|
||||
// 普通阶段用有线轱辘,结尾受力晃动改用无线轱辘;两张图各自使用对应的拆分层。
|
||||
if (IsReelPic(normalized))
|
||||
{
|
||||
basePicName = $"{normalized}{KiteBaseSuffix}";
|
||||
motionPicName = $"{normalized}{KiteMotionSuffix}";
|
||||
@@ -346,6 +452,7 @@ namespace AibisDream
|
||||
return;
|
||||
}
|
||||
|
||||
seq.timeScale = ReelMotionSpeedMultiplier;
|
||||
_smallMotionSequence = seq;
|
||||
}
|
||||
|
||||
@@ -470,6 +577,7 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
seq.OnComplete(() => PlayReelHold(tr, Mathf.Min(1f, strain + 0.22f)));
|
||||
seq.timeScale = ReelMotionSpeedMultiplier;
|
||||
_smallMotionSequence = seq;
|
||||
}
|
||||
|
||||
@@ -510,6 +618,9 @@ namespace AibisDream
|
||||
|
||||
private void ClearLargeImmediate()
|
||||
{
|
||||
StopLargeSpriteAnimation();
|
||||
ApplyLargeSpriteBlur(0f, 0f);
|
||||
|
||||
if (_largeSpriteRenderer != null)
|
||||
{
|
||||
_largeSpriteRenderer.DOKill();
|
||||
@@ -614,7 +725,7 @@ namespace AibisDream
|
||||
var useSplitMotion = TryGetSplitMotionPicNames(picName, out var basePicName, out var motionPicName);
|
||||
var isSamePic = string.Equals(_currentSmallPicName, normalizedName, StringComparison.OrdinalIgnoreCase)
|
||||
&& _currentSmallUsesSplitLayers == useSplitMotion;
|
||||
_smallMotionBaseOffset = normalizedName == "D2S轱辘" ? new Vector3(0f, -0.32f, 0f) : Vector3.zero;
|
||||
_smallMotionBaseOffset = IsReelPic(normalizedName) ? new Vector3(0f, -0.32f, 0f) : Vector3.zero;
|
||||
|
||||
KillSmallTweenState();
|
||||
|
||||
@@ -685,6 +796,8 @@ namespace AibisDream
|
||||
/// <returns>协程</returns>
|
||||
public IEnumerator ShowLargeObj(string picName, float duration = 1)
|
||||
{
|
||||
StopLargeSpriteAnimation();
|
||||
|
||||
// 互斥:小图立刻关掉,避免风筝层与底图不同步淡出造成的怪 fade
|
||||
if (IsSmallShowing)
|
||||
{
|
||||
@@ -721,6 +834,65 @@ namespace AibisDream
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按“前缀1.png … 前缀N.png”加载并循环播放全屏序列帧。
|
||||
/// </summary>
|
||||
public IEnumerator ShowLargeSpriteAnimation(
|
||||
string picNamePrefix,
|
||||
int frameCount,
|
||||
float secondsPerFrame = 0.2f,
|
||||
float duration = 1f)
|
||||
{
|
||||
if (_largeSpriteRenderer == null || frameCount <= 0) yield break;
|
||||
|
||||
StopLargeSpriteAnimation();
|
||||
|
||||
if (IsSmallShowing)
|
||||
{
|
||||
yield return HideObj(0f);
|
||||
}
|
||||
|
||||
if (IsKiteShowing)
|
||||
{
|
||||
yield return HideKite(0f);
|
||||
}
|
||||
|
||||
var frames = new Sprite[frameCount];
|
||||
for (var i = 0; i < frameCount; i++)
|
||||
{
|
||||
var picName = $"{NormalizeDreamPicName(picNamePrefix)}{i + 1}";
|
||||
var key = string.Format(DreamSpritePath, picName);
|
||||
var handle = ResourceSystem.LoadAsync<Sprite>(key);
|
||||
yield return handle;
|
||||
|
||||
if (handle.Status != AsyncOperationStatus.Succeeded || handle.Result == null)
|
||||
{
|
||||
Debug.LogError($"[SpriteShowcase] Failed to load animation frame: {key}");
|
||||
ClearLargeImmediate();
|
||||
yield break;
|
||||
}
|
||||
|
||||
frames[i] = handle.Result;
|
||||
}
|
||||
|
||||
ResetLargePresentationImmediate();
|
||||
_largeSpriteRenderer.gameObject.SetActive(true);
|
||||
_largeSpriteRenderer.sprite = frames[0];
|
||||
_largeSpriteRenderer.SetAlpha(0f);
|
||||
_currentLargePicName = $"{NormalizeDreamPicName(picNamePrefix)}1";
|
||||
_largeSpriteAnimationCoroutine = StartCoroutine(
|
||||
LoopLargeSpriteAnimation(frames, secondsPerFrame));
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
_largeSpriteRenderer.SetAlpha(1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return _largeSpriteRenderer.DOFade(1f, duration).WaitForCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLargeSpriteImmediate(Sprite sprite)
|
||||
{
|
||||
if (_largeSpriteRenderer != null && sprite != null)
|
||||
@@ -799,6 +971,7 @@ namespace AibisDream
|
||||
{
|
||||
if (_largeSpriteRenderer == null) yield break;
|
||||
|
||||
StopLargeSpriteAnimation();
|
||||
KillLargePresentationTweens();
|
||||
if (duration <= 0f)
|
||||
{
|
||||
@@ -811,6 +984,7 @@ namespace AibisDream
|
||||
|
||||
_largeSpriteRenderer.gameObject.SetActive(false);
|
||||
_currentLargePicName = null;
|
||||
ApplyLargeSpriteBlur(0f, 0f);
|
||||
ResetLargePresentationImmediate();
|
||||
}
|
||||
|
||||
@@ -908,7 +1082,7 @@ namespace AibisDream
|
||||
if (_spriteRenderer == null) yield break;
|
||||
|
||||
var normalizedName = NormalizeDreamPicName(picName);
|
||||
_smallMotionBaseOffset = normalizedName == "D2S轱辘" ? new Vector3(0f, -0.32f, 0f) : Vector3.zero;
|
||||
_smallMotionBaseOffset = IsReelPic(normalizedName) ? new Vector3(0f, -0.32f, 0f) : Vector3.zero;
|
||||
_spriteRenderer.gameObject.SetActive(true);
|
||||
|
||||
if (usesSplitLayers)
|
||||
|
||||
@@ -7,14 +7,14 @@ namespace AibisDream
|
||||
{
|
||||
/// <summary>
|
||||
/// Drives the deliberately unsuccessful focus pulls at the start of the
|
||||
/// starfield-to-sea Timeline and keeps the starfield defocused until the
|
||||
/// Timeline reaches the sea.
|
||||
/// starfield-to-sea Timeline. The effect is evaluated from Timeline time so
|
||||
/// pausing, frame drops and repeated playback remain deterministic.
|
||||
/// </summary>
|
||||
public sealed class StarfieldDefocusController : MonoBehaviour
|
||||
{
|
||||
private static readonly int BlurAmountId = Shader.PropertyToID("_BlurAmount");
|
||||
private static readonly int BlurSizeId = Shader.PropertyToID("_BlurSize");
|
||||
private static readonly int UseGaussianBlurId = Shader.PropertyToID("_UseGaussianBlur");
|
||||
private static readonly int UseSoftFocusId = Shader.PropertyToID("_UseSoftFocus");
|
||||
|
||||
[Header("References")]
|
||||
[SerializeField] private PlayableDirector director;
|
||||
@@ -30,34 +30,36 @@ namespace AibisDream
|
||||
[Min(0f)]
|
||||
[SerializeField] private float firstAttemptStart = 0.45f;
|
||||
[Min(0.01f)]
|
||||
[SerializeField] private float firstFocusDuration = 0.82f;
|
||||
[SerializeField] private float firstFocusDuration = 0.48f;
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float firstNearFocusBlur = 0.38f;
|
||||
[Min(0f)]
|
||||
[SerializeField] private float firstHoldDuration = 0.12f;
|
||||
[SerializeField] private float firstHoldDuration = 0.14f;
|
||||
[Min(0.01f)]
|
||||
[SerializeField] private float firstSlipDuration = 0.48f;
|
||||
[SerializeField] private float firstSlipDuration = 0.38f;
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float firstSlipBlur = 0.72f;
|
||||
|
||||
[Header("Focus Attempt 2")]
|
||||
[Min(0f)]
|
||||
[SerializeField] private float secondAttemptStart = 2f;
|
||||
[SerializeField] private float secondAttemptStart = 1.72f;
|
||||
[Min(0.01f)]
|
||||
[SerializeField] private float secondFocusDuration = 0.92f;
|
||||
[SerializeField] private float secondFocusDuration = 0.55f;
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float secondNearFocusBlur = 0.28f;
|
||||
[Min(0f)]
|
||||
[SerializeField] private float secondHoldDuration = 0.14f;
|
||||
[SerializeField] private float secondHoldDuration = 0.18f;
|
||||
[Min(0.01f)]
|
||||
[SerializeField] private float secondSlipDuration = 0.58f;
|
||||
[SerializeField] private float secondSlipDuration = 0.46f;
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float unresolvedBlur = 0.62f;
|
||||
|
||||
[Header("Downward Pan")]
|
||||
[Tooltip("Timeline time at which the starfield starts moving down toward the sea.")]
|
||||
[Min(0f)]
|
||||
[SerializeField] private float descentStart = 4f;
|
||||
[SerializeField] private float blurFadeStart = 4f;
|
||||
[Min(0.01f)]
|
||||
[SerializeField] private float blurFadeDuration = 3.2f;
|
||||
|
||||
private MaterialPropertyBlock propertyBlock;
|
||||
|
||||
@@ -158,7 +160,7 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
director.Pause();
|
||||
SetTimelineTime(descentStart);
|
||||
SetTimelineTime(blurFadeStart);
|
||||
director.Play();
|
||||
|
||||
while (director.state == PlayState.Playing)
|
||||
@@ -246,7 +248,7 @@ namespace AibisDream
|
||||
starfieldRenderer.GetPropertyBlock(propertyBlock);
|
||||
propertyBlock.SetFloat(BlurAmountId, EvaluateBlur(time));
|
||||
propertyBlock.SetFloat(BlurSizeId, blurSize);
|
||||
propertyBlock.SetFloat(UseGaussianBlurId, 1f);
|
||||
propertyBlock.SetFloat(UseSoftFocusId, 1f);
|
||||
starfieldRenderer.SetPropertyBlock(propertyBlock);
|
||||
}
|
||||
|
||||
@@ -306,7 +308,12 @@ namespace AibisDream
|
||||
return SmoothLerp(secondNearFocusBlur, unresolvedBlur, InverseLerp(secondHoldEnd, secondSlipEnd, time));
|
||||
}
|
||||
|
||||
return unresolvedBlur;
|
||||
if (time < blurFadeStart)
|
||||
{
|
||||
return unresolvedBlur;
|
||||
}
|
||||
|
||||
return SmoothLerp(unresolvedBlur, 0f, InverseLerp(blurFadeStart, blurFadeStart + blurFadeDuration, time));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user