feat(huoshan): 添加真话聚合与真假闪切演出命令
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -267,11 +267,11 @@ namespace AibisDream
|
||||
|
||||
public IEnumerator BeginExpressionMemory(
|
||||
string memoryKey,
|
||||
string preset,
|
||||
float fadeDuration = -1f,
|
||||
float pushSpeed = -1f,
|
||||
float horizontalSpeed = -1f,
|
||||
bool preserveGlitch = false)
|
||||
bool preserveGlitch = false,
|
||||
float targetOpacity = 1f)
|
||||
{
|
||||
if (logReleasePresentation == null)
|
||||
{
|
||||
@@ -280,11 +280,11 @@ namespace AibisDream
|
||||
}
|
||||
yield return logReleasePresentation.BeginMemory(
|
||||
memoryKey,
|
||||
preset,
|
||||
fadeDuration,
|
||||
pushSpeed,
|
||||
horizontalSpeed,
|
||||
preserveGlitch);
|
||||
preserveGlitch,
|
||||
targetOpacity);
|
||||
}
|
||||
|
||||
public IEnumerator BeginExpressionLie(string keyword, string preset)
|
||||
|
||||
@@ -232,6 +232,8 @@ namespace AibisDream.MiniGame.Language
|
||||
public Vector3 finalPosition;
|
||||
public Vector3 lieEdgePosition;
|
||||
public int orderIndex;
|
||||
public bool gatherLocked;
|
||||
public Vector3 scatterOffset;
|
||||
}
|
||||
|
||||
private bool focusTweensCompleted = false;
|
||||
@@ -239,8 +241,10 @@ namespace AibisDream.MiniGame.Language
|
||||
private float resolveTotalDurationOverride = -1f;
|
||||
private float lieEdgeCompression;
|
||||
private float lieEdgeJitter;
|
||||
private float truthGatherProgress;
|
||||
private LogReleasePresentationController presentationController;
|
||||
private const string LieCompressionTweenId = "HuoshanLieEdgeCompression";
|
||||
private const string TruthGatherTweenId = "HuoshanTruthGather";
|
||||
|
||||
// 边界
|
||||
private Bounds movementBounds;
|
||||
@@ -1315,6 +1319,8 @@ namespace AibisDream.MiniGame.Language
|
||||
focusMoveTweensCompleted = false;
|
||||
lieEdgeCompression = 0f;
|
||||
lieEdgeJitter = 0f;
|
||||
DOTween.Kill(TruthGatherTweenId);
|
||||
truthGatherProgress = 0f;
|
||||
interferenceLogicSuspended = true;
|
||||
SetStatusUIVisibility(false, statusFadeOutDuration);
|
||||
|
||||
@@ -1480,20 +1486,102 @@ namespace AibisDream.MiniGame.Language
|
||||
{
|
||||
focusTimer += Time.deltaTime;
|
||||
float compression = Mathf.SmoothStep(0f, 1f, lieEdgeCompression);
|
||||
float gather = Mathf.SmoothStep(0f, 1f, truthGatherProgress);
|
||||
int visualCount = Mathf.Max(1, focusVisuals.Count);
|
||||
|
||||
foreach (var visual in focusVisuals.Values)
|
||||
{
|
||||
if (visual == null || visual.particle == null)
|
||||
continue;
|
||||
|
||||
// 真话聚合尝试:悬浮位被拉向最终位置;谎话挤压仍拥有更高优先级
|
||||
Vector3 gatherPosition = Vector3.Lerp(visual.focusPosition, visual.finalPosition, gather);
|
||||
Vector3 compressedPosition = Vector3.Lerp(
|
||||
visual.focusPosition,
|
||||
gatherPosition,
|
||||
visual.lieEdgePosition,
|
||||
compression);
|
||||
Vector3 shuffleOffset = CalculateShuffleOffset(visual, compression, focusTimer) *
|
||||
Mathf.Lerp(1f, 0.18f, compression);
|
||||
Mathf.Lerp(1f, 0.18f, compression) *
|
||||
Mathf.Lerp(1f, 0.12f, gather);
|
||||
Vector3 edgeJitter = CalculateLieEdgeJitter(visual, compression);
|
||||
visual.particle.transform.position = compressedPosition + shuffleOffset + edgeJitter;
|
||||
visual.scatterOffset = Vector3.Lerp(visual.scatterOffset, Vector3.zero, Time.deltaTime * 5.5f);
|
||||
visual.particle.transform.position =
|
||||
compressedPosition + shuffleOffset + edgeJitter + visual.scatterOffset;
|
||||
|
||||
// 锁字判定用原始进度:target=0.92 时阈值 0.95 的最后一个字永远锁不住
|
||||
UpdateTruthGatherLock(visual, truthGatherProgress, visualCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTruthGatherLock(TargetFocusVisual visual, float gather, int visualCount)
|
||||
{
|
||||
// 按字序阶梯式锁定:阈值 0.45~0.95。目标进度 <1 时最后几个字永远差一点锁不住。
|
||||
float lockThreshold = 0.45f + 0.5f * (visual.orderIndex + 1f) / visualCount;
|
||||
if (!visual.gatherLocked && gather >= lockThreshold)
|
||||
{
|
||||
visual.gatherLocked = true;
|
||||
visual.particle.ForceSetCharacter(visual.finalChar);
|
||||
visual.particle.SetChangeInterval(2f);
|
||||
visual.particle.ResetChangeTimer(2f);
|
||||
visual.particle.anxietyShakeIntensity = 0.6f;
|
||||
visual.particle.isStatic = true;
|
||||
}
|
||||
else if (visual.gatherLocked && gather < lockThreshold - 0.08f)
|
||||
{
|
||||
visual.gatherLocked = false;
|
||||
visual.particle.isStatic = false;
|
||||
visual.particle.SetChangeInterval(0.06f);
|
||||
visual.particle.ResetChangeTimer(0.06f);
|
||||
visual.particle.anxietyShakeIntensity = Mathf.Max(visual.particle.anxietyShakeIntensity, 4.5f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 真话聚合尝试(非等待):FocusHolding 下把目标字拉向最终位置并按序逐字锁定。
|
||||
/// target 小于 1 时最后几个字永远差一点锁不住,用于"感觉快要成功了"。
|
||||
/// </summary>
|
||||
public void BeginTruthGather(float target, float duration)
|
||||
{
|
||||
if (completionPhase != CompletionPhase.FocusHolding)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"[LanguageParticleManager] 真话聚合在 {completionPhase} 状态被调用;已安全跳过。");
|
||||
return;
|
||||
}
|
||||
|
||||
DOTween.Kill(TruthGatherTweenId);
|
||||
DOTween.To(
|
||||
() => truthGatherProgress,
|
||||
value => truthGatherProgress = value,
|
||||
Mathf.Clamp01(target),
|
||||
Mathf.Max(0.05f, duration))
|
||||
.SetEase(Ease.InOutSine)
|
||||
.SetId(TruthGatherTweenId)
|
||||
.SetTarget(this);
|
||||
}
|
||||
|
||||
/// <summary>真话聚合被打断:目标字向外爆散并恢复乱跳(非等待)。</summary>
|
||||
public void ScatterTruthGather(float burstDistance)
|
||||
{
|
||||
if (completionPhase != CompletionPhase.FocusHolding)
|
||||
return;
|
||||
|
||||
DOTween.Kill(TruthGatherTweenId);
|
||||
truthGatherProgress = 0f;
|
||||
foreach (TargetFocusVisual visual in focusVisuals.Values)
|
||||
{
|
||||
if (visual?.particle == null)
|
||||
continue;
|
||||
|
||||
visual.gatherLocked = false;
|
||||
Vector2 direction = UnityEngine.Random.insideUnitCircle.normalized;
|
||||
visual.scatterOffset = (Vector3)(direction *
|
||||
Mathf.Max(0f, burstDistance) *
|
||||
UnityEngine.Random.Range(0.6f, 1.3f));
|
||||
visual.particle.isStatic = false;
|
||||
visual.particle.SetChangeInterval(0.05f);
|
||||
visual.particle.ResetChangeTimer(0.05f);
|
||||
visual.particle.anxietyShakeIntensity = Mathf.Max(visual.particle.anxietyShakeIntensity, 6f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1731,6 +1819,8 @@ namespace AibisDream.MiniGame.Language
|
||||
public void PrepareTruthReleaseFromLie()
|
||||
{
|
||||
DOTween.Kill(LieCompressionTweenId);
|
||||
DOTween.Kill(TruthGatherTweenId);
|
||||
truthGatherProgress = 0f;
|
||||
foreach (TargetFocusVisual visual in focusVisuals.Values)
|
||||
{
|
||||
if (visual?.particle == null)
|
||||
@@ -1806,10 +1896,27 @@ namespace AibisDream.MiniGame.Language
|
||||
|
||||
public void SetTruthWarmVisuals(Color warmColor)
|
||||
{
|
||||
ApplyPresentationResolvedVisuals(warmColor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 梳理完成/真话阶段:目标字改为指定色(默认白),并取消加粗以便大屏辨认。
|
||||
/// 玩法阶段颜色不受影响;下一次 start_expression 会通过 RestoreTargetPresentationDefaults 还原。
|
||||
/// </summary>
|
||||
public void ApplyPresentationResolvedVisuals(Color resolvedColor)
|
||||
{
|
||||
Color color = resolvedColor;
|
||||
color.a = 1f;
|
||||
foreach (CandidateParticle particle in targetParticles)
|
||||
{
|
||||
if (particle == null) continue;
|
||||
particle.SetColors(targetParticleColor, nonTargetParticleColor, nonTargetParticleColor, warmColor);
|
||||
particle.SetColors(color, nonTargetParticleColor, nonTargetParticleColor, color);
|
||||
particle.calmProgress = 1f;
|
||||
particle.SetFontStyles(
|
||||
targetParticleFontSize,
|
||||
nonTargetParticleFontSize,
|
||||
false,
|
||||
nonTargetParticleBold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1900,6 +2007,8 @@ namespace AibisDream.MiniGame.Language
|
||||
}
|
||||
|
||||
DOTween.Kill(LieCompressionTweenId);
|
||||
DOTween.Kill(TruthGatherTweenId);
|
||||
truthGatherProgress = 0f;
|
||||
StopSlotMachineShuffle();
|
||||
completionPhase = CompletionPhase.Focusing;
|
||||
focusTweensCompleted = true;
|
||||
@@ -1932,6 +2041,8 @@ namespace AibisDream.MiniGame.Language
|
||||
public void RestoreTargetPresentationDefaults(float alphaValue = 1f)
|
||||
{
|
||||
DOTween.Kill(LieCompressionTweenId);
|
||||
DOTween.Kill(TruthGatherTweenId);
|
||||
truthGatherProgress = 0f;
|
||||
StopSlotMachineShuffle();
|
||||
foreach (CandidateParticle particle in targetParticles)
|
||||
{
|
||||
@@ -1940,6 +2051,11 @@ namespace AibisDream.MiniGame.Language
|
||||
particle.alpha = Mathf.Clamp01(alphaValue);
|
||||
particle.calmProgress = 0f;
|
||||
particle.SetColors(targetParticleColor, nonTargetParticleColor, nonTargetParticleColor, targetCalmColor);
|
||||
particle.SetFontStyles(
|
||||
targetParticleFontSize,
|
||||
nonTargetParticleFontSize,
|
||||
targetParticleBold,
|
||||
nonTargetParticleBold);
|
||||
}
|
||||
resolveTotalDurationOverride = -1f;
|
||||
lieEdgeCompression = 0f;
|
||||
@@ -1997,6 +2113,7 @@ namespace AibisDream.MiniGame.Language
|
||||
|
||||
lieEdgeCompression = 0f;
|
||||
lieEdgeJitter = 0f;
|
||||
truthGatherProgress = 0f;
|
||||
completionPhase = CompletionPhase.Finished;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AibisDream.FixSystem;
|
||||
using AibisDream;
|
||||
@@ -179,28 +179,44 @@ namespace AibisDream.MiniGame.Language
|
||||
yield return ExpressionManager.StartCoroutine(ExpressionManager.TransitionGlitchAndWait(to, duration));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记忆淡入(非阻塞):透明度在 fadeDuration 内显现,画面同时按 pushSpeed 持续推近;
|
||||
/// targetOpacity 是本次淡入的目标透明度。horizontalSpeed 为旧 Yarn 兼容参数,基础层不再横移。
|
||||
/// 争夺段的 jolt / tear / impact 仍会叠加。
|
||||
/// </summary>
|
||||
[YarnCommand("expression_memory_begin")]
|
||||
public static IEnumerator ExpressionMemoryBegin(
|
||||
public static void ExpressionMemoryBegin(
|
||||
string memoryKey,
|
||||
string preset,
|
||||
float fadeDuration = -1f,
|
||||
float pushSpeed = -1f,
|
||||
float horizontalSpeed = -1f,
|
||||
bool preserveGlitch = false)
|
||||
bool preserveGlitch = false,
|
||||
float targetOpacity = 1f)
|
||||
{
|
||||
if (ExpressionManager == null)
|
||||
{
|
||||
UnityEngine.Debug.LogError("ExpressionManager 未找到!");
|
||||
yield break;
|
||||
return;
|
||||
}
|
||||
yield return ExpressionManager.StartCoroutine(
|
||||
ExpressionManager.StartCoroutine(
|
||||
ExpressionManager.BeginExpressionMemory(
|
||||
memoryKey,
|
||||
preset,
|
||||
fadeDuration,
|
||||
pushSpeed,
|
||||
horizontalSpeed,
|
||||
preserveGlitch));
|
||||
preserveGlitch,
|
||||
targetOpacity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 随对白把当前记忆透明度推进到目标值(非阻塞)。
|
||||
/// <<expression_memory_alpha 0.65 0.45>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_memory_alpha")]
|
||||
public static void ExpressionMemoryAlpha(float target, float duration = 0.4f)
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.SetActiveMemoryOpacity(target, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -315,6 +331,85 @@ namespace AibisDream.MiniGame.Language
|
||||
presentation.PlayMemoryJolt(offset, duration, tear);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调节记忆的轻微失真扰动(非阻塞)。默认强度由演出预设决定,本命令用于演出中微调。
|
||||
/// <<expression_memory_sim 0.55 0.3>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_memory_sim")]
|
||||
public static void ExpressionMemorySim(float target, float duration = 0.3f)
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.SetSimulationGlitch(target, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 真话聚合尝试(非阻塞):目标字被慢慢拉向最终位置并按字序逐个锁定成真心话。
|
||||
/// target 小于 1 时最后几个字永远差一点锁不住——"感觉快要成功了"。
|
||||
/// <<expression_truth_gather 0.9 3.2>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_truth_gather")]
|
||||
public static void ExpressionTruthGather(float target = 0.9f, float duration = 3f)
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.BeginTruthGatherAttempt(target, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 真话聚合被打断(非阻塞):目标字向外爆散并恢复乱跳。burst 为世界单位的爆散距离。
|
||||
/// <<expression_truth_scatter 0.9>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_truth_scatter")]
|
||||
public static void ExpressionTruthScatter(float burst = 0.9f)
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.ScatterTruthGatherAttempt(burst);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 火山脸错误闪红(非阻塞):聚合失败时短暂替换红屏 Sprite,随后恢复,并轻微下沉。
|
||||
/// <<expression_face_error 0.5 0.85>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_face_error")]
|
||||
public static void ExpressionFaceError(float duration = 0.5f, float intensity = 0.85f)
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.PlayFaceErrorFlash(duration, intensity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 结尾真假快速闪切(非阻塞,节奏由同长度 wait 控制):真心话与谎话交替独占屏幕,
|
||||
/// 两者的屏幕底色(电视头背景)不同,越到后面切得越快,结束定格在真话帧。
|
||||
/// <<expression_truth_lie_flicker "没问题|冇问题|帽问题" "我就是个笑话" 3.2 0.24 12>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_truth_lie_flicker")]
|
||||
public static void ExpressionTruthLieFlicker(
|
||||
string liePhrases,
|
||||
string truthPhrase,
|
||||
float duration,
|
||||
float interval = 0.24f,
|
||||
float fontSize = 12f)
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.StartTruthLieFlicker(liePhrases, truthPhrase, duration, interval, fontSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定格的谎话被 glitch 翻转成真话(阻塞):大字乱跳中长度从谎话渐变到真话、真假底色抢闪,
|
||||
/// 最后落在暖色真话。紧接 expression_memory_cut + expression_truth_snap 收尾。
|
||||
/// <<expression_lie_morph_truth "没问题" "我就是个笑话" 0.9>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_lie_morph_truth")]
|
||||
public static IEnumerator ExpressionLieMorphTruth(
|
||||
string lieText,
|
||||
string truthText,
|
||||
float duration = 0.9f)
|
||||
{
|
||||
if (!TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
yield break;
|
||||
yield return ExpressionManager.StartCoroutine(
|
||||
presentation.MorphLieToTruth(lieText, truthText, duration));
|
||||
}
|
||||
|
||||
[YarnCommand("expression_truth_leak")]
|
||||
public static IEnumerator ExpressionTruthLeak(string fragment, float duration)
|
||||
{
|
||||
@@ -336,7 +431,7 @@ namespace AibisDream.MiniGame.Language
|
||||
|
||||
/// <summary>
|
||||
/// 演员大字闪现(阻塞):抖动的粒子字瞬间隐藏,屏幕中央出现白色大字(红青色散双影+急速缩放),
|
||||
/// 停顿 holdDuration 秒后恢复粒子字抖动。
|
||||
/// 停顿 holdDuration 秒后始终恢复粒子字抖动;结尾定格请使用 expression_actor_flash_in。
|
||||
/// <<expression_actor_flash "没问题" 0.6 10.5 1.15 1.60 0.03 0.22 0.5 0.2>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_actor_flash")]
|
||||
@@ -366,19 +461,95 @@ namespace AibisDream.MiniGame.Language
|
||||
glitchPeak));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 演员大字入场并保持(阻塞):入场表现与 expression_actor_flash 相同,但不执行退场,
|
||||
/// 适合在段落结尾定格。后续清场命令仍会正常移除它。
|
||||
/// <<expression_actor_flash_in "没问题" 0.35 10.5 1.1 1.45 0.008 0.06 0.5 0>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_actor_flash_in")]
|
||||
public static IEnumerator ExpressionActorFlashIn(
|
||||
string text,
|
||||
float holdDuration = 0.35f,
|
||||
float fontSize = 10.5f,
|
||||
float settledScale = -1f,
|
||||
float punchScale = -1f,
|
||||
float chromaDistance = -1f,
|
||||
float chromaAlpha = -1f,
|
||||
float impact = -1f,
|
||||
float glitchPeak = -1f)
|
||||
{
|
||||
if (!TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
yield break;
|
||||
yield return ExpressionManager.StartCoroutine(
|
||||
presentation.FlashActorLie(
|
||||
text,
|
||||
holdDuration,
|
||||
fontSize,
|
||||
settledScale,
|
||||
punchScale,
|
||||
chromaDistance,
|
||||
chromaAlpha,
|
||||
impact,
|
||||
glitchPeak,
|
||||
true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 非阻塞启动“没问题 → 冇问题 → 帽问题”三拍无限闪现循环。
|
||||
/// <<expression_actor_flash_loop_start>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_actor_flash_loop_start")]
|
||||
public static void ExpressionActorFlashLoopStart()
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.StartActorFlashLoop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 立即停止无限闪现循环、清除当前大字,并恢复晃动粒子字。
|
||||
/// <<expression_actor_flash_loop_stop>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_actor_flash_loop_stop")]
|
||||
public static void ExpressionActorFlashLoopStop()
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.StopActorFlashLoop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 真话闪现(阻塞):谎话大字之间,暖色完整真话带细微抖动挣扎浮现一拍;
|
||||
/// "被掐断"由紧随其后的 expression_glitch_pulse 表现。不推进谎话冲击等级。
|
||||
/// <<expression_actor_truth_flash "我就是个笑话" 0.35 8.5 0.55 0.02>>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_actor_truth_flash")]
|
||||
public static IEnumerator ExpressionActorTruthFlash(
|
||||
string text,
|
||||
float holdDuration = 0.35f,
|
||||
float fontSize = 8.5f,
|
||||
float alpha = 0.8f,
|
||||
float jitter = 0.02f)
|
||||
{
|
||||
if (!TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
yield break;
|
||||
yield return ExpressionManager.StartCoroutine(
|
||||
presentation.FlashActorTruth(text, holdDuration, fontSize, alpha, jitter));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 老虎机换字(非阻塞,节拍由 Yarn wait 控制):聚焦字在 duration 内只从 charPool 里疯狂换字。
|
||||
/// <<expression_actor_slot "没问题冇" 5 0.05 14>>
|
||||
/// truthPool 非空时其字符也混入换字池,并以真话暖色显示。
|
||||
/// <<expression_actor_slot "没问题冇" 5 0.05 14 "我就是个笑话">>
|
||||
/// </summary>
|
||||
[YarnCommand("expression_actor_slot")]
|
||||
public static void ExpressionActorSlot(
|
||||
string charPool,
|
||||
float duration,
|
||||
float interval = 0.05f,
|
||||
float fontSize = 14f)
|
||||
float fontSize = 14f,
|
||||
string truthPool = "")
|
||||
{
|
||||
if (TryGetPresentation(out LogReleasePresentationController presentation))
|
||||
presentation.StartActorSlotMachine(charPool, duration, interval, fontSize);
|
||||
presentation.StartActorSlotMachine(charPool, duration, interval, fontSize, truthPool);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -588,4 +759,3 @@ namespace AibisDream.MiniGame.Language
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ Shader "AibisDream/HuoshanMemory"
|
||||
_Contrast("Contrast", Range(0, 2)) = 1
|
||||
_Vignette("Vignette", Range(0, 1)) = 0
|
||||
_Noise("Noise", Range(0, 1)) = 0
|
||||
_SimGlitch("Simulation Glitch", Range(0, 1)) = 0
|
||||
_HorizontalTear("Horizontal Tear", Range(0, 1)) = 0
|
||||
_Impact("Transient Memory Impact", Range(0, 1)) = 0
|
||||
_Damage("Accumulated Memory Damage", Range(0, 1)) = 0
|
||||
@@ -74,6 +75,7 @@ Shader "AibisDream/HuoshanMemory"
|
||||
float _Contrast;
|
||||
float _Vignette;
|
||||
float _Noise;
|
||||
float _SimGlitch;
|
||||
float _HorizontalTear;
|
||||
float _Impact;
|
||||
float _Damage;
|
||||
@@ -114,6 +116,9 @@ Shader "AibisDream/HuoshanMemory"
|
||||
calmMask *= step(0.001, _CalmRadius);
|
||||
float effect = saturate(_EffectStrength) * (1.0 - calmMask);
|
||||
|
||||
// Small persistent simulation disturbance, independent of the impact path.
|
||||
float sim = saturate(_SimGlitch) * (1.0 - calmMask * 0.85);
|
||||
|
||||
float impact = saturate(_Impact);
|
||||
float damage = saturate(_Damage);
|
||||
float overdrive = saturate(_Overdrive);
|
||||
@@ -142,6 +147,17 @@ Shader "AibisDream/HuoshanMemory"
|
||||
impact * 0.060 +
|
||||
overdrive * 0.082;
|
||||
sampleUV.x += tearDirection * tearGate * tearAmount * distortion;
|
||||
|
||||
// Subtle continuous UV wobble plus an occasional narrow-row slip.
|
||||
sampleUV.x += sin((input.uv.y * 18.0 + _Time.y * 0.8) * 6.28318) * 0.0012 * sim;
|
||||
sampleUV.y += sin((input.uv.x * 13.0 - _Time.y * 0.55) * 6.28318) * 0.0007 * sim;
|
||||
float simSlot = floor(_Time.y * 0.9 + _TearSeed * 7.0);
|
||||
float simGate = step(0.62, hash21(float2(simSlot, 3.7)));
|
||||
float simRow = floor(input.uv.y * 34.0);
|
||||
float simRowPick = step(0.90, hash21(float2(simRow + simSlot * 13.0, 11.3)));
|
||||
float simJitterDir = hash21(float2(simSlot * 1.37, simRow)) * 2.0 - 1.0;
|
||||
sampleUV.x += simJitterDir * simGate * simRowPick * 0.0035 * sim;
|
||||
|
||||
sampleUV.y = (sampleUV.y - 0.5) *
|
||||
(1.0 + impact * 0.016 + overdrive * 0.025) + 0.5;
|
||||
sampleUV = saturate(sampleUV);
|
||||
@@ -194,7 +210,9 @@ Shader "AibisDream/HuoshanMemory"
|
||||
hash21(float2(dropoutRow * 3.17, timeStep)));
|
||||
graded *= lerp(1.0, dropoutLevel, dropoutGate * overdrive * 0.72);
|
||||
|
||||
float3 finalColor = lerp(original.rgb, graded, distortion);
|
||||
// The simulation path only opens a light amount of grading/distortion.
|
||||
float3 finalColor = lerp(original.rgb, graded, max(distortion, sim * 0.45));
|
||||
|
||||
return half4(
|
||||
finalColor * input.color.rgb,
|
||||
original.a * input.color.a * _Opacity);
|
||||
|
||||
Reference in New Issue
Block a user