fix: 气泡时序问题
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user