fix(huoshan): 优化语言粒子布局与状态重置
This commit is contained in:
@@ -9259,9 +9259,9 @@ MonoBehaviour:
|
||||
_ambientNoiseScale: 320
|
||||
_ambientNoiseBrightness: 0.55
|
||||
_calmFieldPadding: {x: 0.55, y: 0.4}
|
||||
_calmFieldFeather: 0.45
|
||||
_calmFieldResidualIntensity: 0.04
|
||||
_calmFieldBoundaryWarp: 0.025
|
||||
_calmFieldFeather: 0.85
|
||||
_calmFieldResidualIntensity: 0.08
|
||||
_calmFieldBoundaryWarp: 0.05
|
||||
_calmFieldTransitionDuration: 0.45
|
||||
--- !u!1 &751535848
|
||||
GameObject:
|
||||
@@ -15057,7 +15057,7 @@ MonoBehaviour:
|
||||
defaultTargetSentence: "\u8FD9\u662F\u4E00\u4E2A\u6D4B\u8BD5\u793A\u4F8B"
|
||||
spriteRenderer: {fileID: 2468058580162010626}
|
||||
glitchController: {fileID: 741515695}
|
||||
ambientNoiseDensity: 0.06
|
||||
ambientNoiseDensity: 0
|
||||
ambientNoiseScale: 360
|
||||
ambientNoiseBrightness: 0.5
|
||||
--- !u!114 &2138889541
|
||||
@@ -17270,13 +17270,13 @@ MonoBehaviour:
|
||||
shakeSpeed: 10
|
||||
changeInterval: 0.28
|
||||
floatAmplitude: 0.02
|
||||
glitchBaselineMax: 0.08
|
||||
glitchBaselineMax: 0
|
||||
driftBias: 0.1
|
||||
- shakeIntensity: 0.05
|
||||
shakeSpeed: 12
|
||||
changeInterval: 0.18
|
||||
floatAmplitude: 0.028
|
||||
glitchBaselineMax: 0.15
|
||||
glitchBaselineMax: 0
|
||||
driftBias: 0.15
|
||||
targetConnectionThickness: 0.02
|
||||
nonTargetConnectionThickness: 0.012
|
||||
@@ -17310,7 +17310,7 @@ MonoBehaviour:
|
||||
completionBlastForce: 3.5
|
||||
completionBlastAlphaRatio: 0.35
|
||||
completionCalmDelay: 0.55
|
||||
completionGlitchPulsePeak: 0.25
|
||||
completionGlitchPulsePeak: 0
|
||||
confirmButtonFadeDuration: 0.35
|
||||
confirmButtonRiseOffset: 0.35
|
||||
panelStartAtEntranceProgress: 0.6
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace AibisDream
|
||||
|
||||
[Header("常驻细密噪点(不随 glitch 强度消失,营造老屏幕底噪)")]
|
||||
[Tooltip("常驻噪点密度,0 = 关闭(恢复旧行为:LOG1 无噪点)")]
|
||||
[SerializeField, Range(0f, 0.3f)] private float ambientNoiseDensity = 0.06f;
|
||||
[SerializeField, Range(0f, 0.3f)] private float ambientNoiseDensity = 0f;
|
||||
[Tooltip("噪点细密程度,越大颗粒越细(glitch 主噪点默认 80)")]
|
||||
[SerializeField, Range(80f, 800f)] private float ambientNoiseScale = 360f;
|
||||
[Tooltip("常驻噪点亮度(低于 glitch 主噪点,保持底噪感)")]
|
||||
@@ -126,6 +126,7 @@ namespace AibisDream
|
||||
// 新一轮重置干扰联动(解除 yarn 覆盖、基线归零)
|
||||
yarnGlitchOverride = false;
|
||||
gameplayGlitchBaseline = 0f;
|
||||
glitchController?.TransitionTo(0f, 0.25f);
|
||||
|
||||
if (particleManager != null)
|
||||
{
|
||||
@@ -163,6 +164,7 @@ namespace AibisDream
|
||||
public IEnumerator FadeOutParticlesBeforeNewRound(float duration = 0f)
|
||||
{
|
||||
glitchController?.ClearCalmField(true);
|
||||
glitchController?.TransitionTo(0f, 0.25f);
|
||||
|
||||
if (particleManager == null) yield break;
|
||||
yield return StartCoroutine(particleManager.FadeOutBeforeNewExpressionRound(duration));
|
||||
@@ -204,6 +206,7 @@ namespace AibisDream
|
||||
public void CloseView()
|
||||
{
|
||||
glitchController?.ClearCalmField(true);
|
||||
glitchController?.TransitionTo(0f, 0f);
|
||||
|
||||
if (expressionView != null)
|
||||
{
|
||||
@@ -222,6 +225,7 @@ namespace AibisDream
|
||||
public void ResetSystem(bool playEntranceEffect = true)
|
||||
{
|
||||
glitchController?.ClearCalmField(true);
|
||||
glitchController?.TransitionTo(0f, 0.25f);
|
||||
|
||||
if (particleManager != null)
|
||||
{
|
||||
|
||||
@@ -117,12 +117,12 @@ namespace AibisDream.MiniGame.Language
|
||||
new InterferencePresentationPreset
|
||||
{
|
||||
shakeIntensity = 0.035f, shakeSpeed = 10f, changeInterval = 0.28f,
|
||||
floatAmplitude = 0.02f, glitchBaselineMax = 0.08f, driftBias = 0.25f
|
||||
floatAmplitude = 0.02f, glitchBaselineMax = 0f, driftBias = 0.25f
|
||||
},
|
||||
new InterferencePresentationPreset
|
||||
{
|
||||
shakeIntensity = 0.05f, shakeSpeed = 12f, changeInterval = 0.18f,
|
||||
floatAmplitude = 0.028f, glitchBaselineMax = 0.15f, driftBias = 0.4f
|
||||
floatAmplitude = 0.028f, glitchBaselineMax = 0f, driftBias = 0.4f
|
||||
},
|
||||
};
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace AibisDream.MiniGame.Language
|
||||
[Tooltip("吹散后到进入平静态的延迟(秒)")]
|
||||
[SerializeField] private float completionCalmDelay = 0.55f;
|
||||
[Tooltip("完成瞬间 glitch 脉冲峰值(0 关闭)")]
|
||||
[SerializeField, Range(0f, 1f)] private float completionGlitchPulsePeak = 0.25f;
|
||||
[SerializeField, Range(0f, 1f)] private float completionGlitchPulsePeak = 0f;
|
||||
|
||||
[Header("节奏统一")]
|
||||
[Tooltip("完成时确认按钮淡入/上浮时长(秒)")]
|
||||
@@ -1264,37 +1264,6 @@ namespace AibisDream.MiniGame.Language
|
||||
}
|
||||
|
||||
// 激活 button 并淡入上浮(不可交互,播放火山表达确认后再解锁),与确认 timeline 并行
|
||||
if (focusSequenceButton != null)
|
||||
{
|
||||
var btnCg = focusSequenceButton.GetComponent<CanvasGroup>();
|
||||
if (btnCg == null)
|
||||
btnCg = focusSequenceButton.gameObject.AddComponent<CanvasGroup>();
|
||||
var btnRect = focusSequenceButton.transform as RectTransform;
|
||||
if (btnRect != null && !confirmButtonBasePosCaptured)
|
||||
{
|
||||
confirmButtonBaseAnchoredPos = btnRect.anchoredPosition;
|
||||
confirmButtonBasePosCaptured = true;
|
||||
}
|
||||
|
||||
focusSequenceButton.gameObject.SetActive(true);
|
||||
focusSequenceButton.interactable = false;
|
||||
|
||||
DOTween.Kill(btnCg);
|
||||
btnCg.alpha = 0f;
|
||||
btnCg.DOFade(1f, confirmButtonFadeDuration).SetEase(Ease.OutQuad);
|
||||
if (btnRect != null)
|
||||
{
|
||||
btnRect.DOKill();
|
||||
btnRect.anchoredPosition = confirmButtonBaseAnchoredPos + Vector2.down * confirmButtonRiseOffset;
|
||||
btnRect.DOAnchorPos(confirmButtonBaseAnchoredPos, confirmButtonFadeDuration).SetEase(Ease.OutQuad);
|
||||
}
|
||||
}
|
||||
if (confirmTimelineRoutine != null)
|
||||
{
|
||||
StopCoroutine(confirmTimelineRoutine);
|
||||
}
|
||||
confirmTimelineRoutine = StartCoroutine(PlayConfirmTimelineAndUnlockButton());
|
||||
|
||||
foreach (var particle in candidateParticles)
|
||||
{
|
||||
if (!particle.isRed)
|
||||
@@ -1319,6 +1288,135 @@ namespace AibisDream.MiniGame.Language
|
||||
/// 延迟后进入平静态;同时打一次 glitch 短脉冲。
|
||||
/// </summary>
|
||||
private void PlayCompletionBurst()
|
||||
{
|
||||
if (completionBurstRoutine != null)
|
||||
{
|
||||
StopCoroutine(completionBurstRoutine);
|
||||
}
|
||||
completionBurstRoutine = StartCoroutine(PlayCalmCompletionRoutine());
|
||||
}
|
||||
|
||||
private IEnumerator PlayCalmCompletionRoutine()
|
||||
{
|
||||
float fadeDuration = Mathf.Max(0.05f, completionCalmDelay);
|
||||
float moveDuration = Mathf.Max(0.05f, completionShockwaveDuration);
|
||||
|
||||
if (connectionRenderer != null)
|
||||
{
|
||||
DOTween.To(() => connectionRenderer.NonTargetAlphaScale, v => connectionRenderer.NonTargetAlphaScale = v, 0f, fadeDuration)
|
||||
.SetEase(Ease.OutQuad)
|
||||
.SetTarget(this);
|
||||
}
|
||||
|
||||
foreach (var particle in candidateParticles)
|
||||
{
|
||||
if (particle == null)
|
||||
continue;
|
||||
|
||||
particle.velocity = Vector2.zero;
|
||||
if (!particle.isRed)
|
||||
{
|
||||
particle.isCalmed = true;
|
||||
particle.isStatic = true;
|
||||
FadeOutTextParticle(particle, fadeDuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
particle.isStatic = true;
|
||||
particle.isCalmed = true;
|
||||
particle.changeSpeedMultiplier = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var particle in floatingParticles)
|
||||
{
|
||||
if (particle == null)
|
||||
continue;
|
||||
|
||||
particle.isCalmed = true;
|
||||
particle.velocity = Vector2.zero;
|
||||
FadeOutTextParticle(particle, fadeDuration);
|
||||
}
|
||||
|
||||
int tweenTargetCount = orderedRedParticles.Count;
|
||||
int completedTweens = 0;
|
||||
for (int i = 0; i < orderedRedParticles.Count; i++)
|
||||
{
|
||||
var particle = orderedRedParticles[i];
|
||||
if (particle == null)
|
||||
{
|
||||
completedTweens++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i < finalTargetCharacters.Count)
|
||||
{
|
||||
particle.ForceSetCharacter(finalTargetCharacters[i]);
|
||||
}
|
||||
|
||||
Vector3 targetPos = finalTargetPositions.Count > i
|
||||
? finalTargetPositions[i]
|
||||
: (worldCanvas != null ? worldCanvas.transform.position : Vector3.zero);
|
||||
|
||||
particle.alpha = particle.baseAlpha;
|
||||
particle.transform.DOKill();
|
||||
particle.transform.DOMove(targetPos, moveDuration)
|
||||
.SetEase(Ease.InOutQuad)
|
||||
.OnComplete(() => completedTweens++);
|
||||
particle.transform.DOScale(Vector3.one * focusZoomScale, moveDuration).SetEase(Ease.OutQuad);
|
||||
}
|
||||
|
||||
if (tweenTargetCount > 0)
|
||||
{
|
||||
while (completedTweens < tweenTargetCount)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WaitForSeconds(fadeDuration);
|
||||
}
|
||||
|
||||
ShowFocusSequenceButton();
|
||||
if (confirmTimelineRoutine != null)
|
||||
{
|
||||
StopCoroutine(confirmTimelineRoutine);
|
||||
}
|
||||
confirmTimelineRoutine = StartCoroutine(PlayConfirmTimelineAndUnlockButton());
|
||||
completionBurstRoutine = null;
|
||||
}
|
||||
|
||||
private void ShowFocusSequenceButton()
|
||||
{
|
||||
if (focusSequenceButton == null)
|
||||
return;
|
||||
|
||||
var btnCg = focusSequenceButton.GetComponent<CanvasGroup>();
|
||||
if (btnCg == null)
|
||||
btnCg = focusSequenceButton.gameObject.AddComponent<CanvasGroup>();
|
||||
var btnRect = focusSequenceButton.transform as RectTransform;
|
||||
if (btnRect != null && !confirmButtonBasePosCaptured)
|
||||
{
|
||||
confirmButtonBaseAnchoredPos = btnRect.anchoredPosition;
|
||||
confirmButtonBasePosCaptured = true;
|
||||
}
|
||||
|
||||
focusSequenceButton.gameObject.SetActive(true);
|
||||
focusSequenceButton.interactable = false;
|
||||
|
||||
DOTween.Kill(btnCg);
|
||||
btnCg.alpha = 0f;
|
||||
btnCg.DOFade(1f, confirmButtonFadeDuration).SetEase(Ease.OutQuad);
|
||||
if (btnRect != null)
|
||||
{
|
||||
btnRect.DOKill();
|
||||
btnRect.anchoredPosition = confirmButtonBaseAnchoredPos + Vector2.down * confirmButtonRiseOffset;
|
||||
btnRect.DOAnchorPos(confirmButtonBaseAnchoredPos, confirmButtonFadeDuration).SetEase(Ease.OutQuad);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayCompletionBurstLegacy()
|
||||
{
|
||||
Vector3 center = ComputeCentroid(targetParticles);
|
||||
|
||||
@@ -1523,10 +1621,7 @@ namespace AibisDream.MiniGame.Language
|
||||
for (int i = 0; i < orderedRedParticles.Count; i++)
|
||||
{
|
||||
var particle = orderedRedParticles[i];
|
||||
Vector3 offset = particle.transform.position - focusCentroid;
|
||||
float indexCenter = (orderedRedParticles.Count - 1) * 0.5f;
|
||||
Vector3 spreadOffset = new Vector3((i - indexCenter) * spreadDistance, Mathf.Sin(i * 1.4f) * spreadDistance * 0.6f, 0f);
|
||||
Vector3 focusPosition = focusTargetCenter + offset * focusZoomScale + spreadOffset;
|
||||
Vector3 focusPosition = particle.transform.position;
|
||||
Vector3 finalPosition = finalTargetPositions.Count > i ? finalTargetPositions[i] : focusTargetCenter;
|
||||
focusPosition = ClampPositionToBounds(focusPosition, focusClipBounds);
|
||||
finalPosition = ClampPositionToBounds(finalPosition, focusClipBounds);
|
||||
|
||||
Reference in New Issue
Block a user