fix: 气泡时序问题

This commit is contained in:
2026-07-22 00:07:54 +08:00
parent 3891b6bd37
commit 3919ea9a75
7 changed files with 57 additions and 10 deletions
@@ -128,6 +128,15 @@ namespace AibisDream
public async void TextShown()
{
// UI completion events can arrive more than once (for example, when a typewriter is
// reused or a previous line finishes late). Only the active PlayText state is allowed
// to enter the post-display delay; otherwise a stale callback could regress a token
// from Advanced, or run before TextStart and corrupt the line lifecycle.
if (state != LineSyncState.PlayText)
{
return;
}
AdvanceDelayToken = new CancellationTokenSource();
EnumEventSystem.Global.Send(DialogEventEnum.LineShown);
await _textShown.OnTextShown(this);
@@ -43,6 +43,7 @@ namespace AibisDream.FixSystem
{
EnumEventSystem.Global.Send(ScreenEventEnum.Selected, gameObject);
logText.PrepareForLine();
logText.OnTextShown += () => token.TextShown();
bool isWarning = string.Equals(token.lineInfo.character.key, WarningCharacterKey,
@@ -52,8 +53,8 @@ namespace AibisDream.FixSystem
title.color = isWarning ? WarningRedColor : AmberColor;
title.text = token.lineInfo.character.GetActorName();
logText.SetTypewriterSpeed(GetTextSpeedValue());
logText.AddText(token.lineInfo.lineText);
token.TextStart();
logText.AddText(token.lineInfo.lineText);
}
else
{
@@ -205,6 +205,7 @@ namespace AibisDream
}
yield return SubwayCenter.StateMachine.SwitchState(targetState);
yield return null;
}
[YarnCommand("arrive_at_station")]
@@ -135,6 +135,20 @@ namespace AibisDream.UI
#region
/// <summary>
/// 在注册新台词完成回调前停止旧动画,并丢弃可能迟到的旧回调。
/// 保留终端中已经显示的历史文本。
/// </summary>
public void PrepareForLine()
{
if (typewriter != null)
{
typewriter.StopShowingText();
}
OnTextShown = null;
}
/// <summary>
/// 添加新文本(追加到现有文本)
/// </summary>
+15 -3
View File
@@ -45,6 +45,11 @@ namespace AibisDream
_bubbleGroup = bubbleGroup;
InitRefs();
// Dialogue playback is started explicitly by BubbleGroup. OnEnable playback can
// resume fully displayed text when a pooled bubble is reactivated and synchronously
// emit onTextShowed for the wrong line.
_typewriter.startTypewriterMode = TypewriterCore.StartTypewriterMode.OnShowText;
role = data.actorRole;
idx = data.idx;
maxWidth = data.maxWidth;
@@ -119,10 +124,16 @@ namespace AibisDream
: characterVo.GetActorName();
}
public void PrepareForLine()
{
_typewriter.StopShowingText();
OnLineShown = null;
gameObject.SetActive(true);
_typewriter.TextAnimator.SetText(string.Empty);
}
public void ShowLine(string line)
{
_typewriter.TextAnimator.SetText("");
gameObject.SetActive(true);
HandleLayout(line);
_typewriter.ShowText(line);
}
@@ -215,9 +226,10 @@ namespace AibisDream
public int Idx { get; }
public event Action OnLineShown;
public void PrepareForLine();
public void ShowActorName(CharacterVo characterVo);
public void ShowLine(string line);
public bool SkipLine();
public void Hide();
}
}
}
@@ -73,14 +73,19 @@ namespace AibisDream
if (TryGetBubble(character.role, character.bubbleIdx, out var bubble))
{
// Stop the previous typewriter and remove its completion callback before the new
// token is registered. A forcibly advanced line may otherwise finish late and
// complete the next token.
bubble.PrepareForLine();
// 注册事件
bubble.OnLineShown += syncToken.TextShown;
syncToken.SkipTextAnima += () => bubble.SkipLine();
syncToken.OnAdvance += AfterAdvance;
// 播放文字
bubble.ShowActorName(character);
bubble.ShowLine(syncToken.lineInfo.lineText);
syncToken.TextStart();
bubble.ShowLine(syncToken.lineInfo.lineText);
// 将非选定的Bubble隐藏
HideDialog(bubble);
}
@@ -138,4 +143,4 @@ namespace AibisDream
#endregion
}
}
}
+9 -4
View File
@@ -24,6 +24,13 @@ namespace AibisDream
// 先中断结束事件
_autoHideToken?.Cancel();
_autoHideToken = null;
OnTextShowed = null;
// 先停止旧动画并准备好激活状态,避免 OnEnable 或旧动画完成事件命中新 token。
content.StopShowingText();
box.SetActive(true);
content.StopShowingText();
content.TextAnimator.SetText(string.Empty);
// 注册事件
OnTextShowed += syncToken.TextShown;
@@ -31,10 +38,8 @@ namespace AibisDream
syncToken.OnAdvance += AfterAdvance;
// 播放文字
content.TextAnimator.SetText(string.Empty);
box.SetActive(true);
content.ShowText(syncToken.lineInfo.lineText);
syncToken.TextStart();
content.ShowText(syncToken.lineInfo.lineText);
}
private async void AfterAdvance()
@@ -109,4 +114,4 @@ namespace AibisDream
HideDialog();
}
}
}
}