调整 Directive 逻辑并添加章节之间的承接功能

This commit is contained in:
SepComet
2026-04-24 14:15:40 +08:00
parent facfe7a437
commit d557153e28
18 changed files with 164999 additions and 163916 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 99d811b0183246646a2ce8df996f4bca
guid: 98380886ef3ddab4e913ead8133a2e42
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
+1 -1
View File
@@ -10,7 +10,7 @@ MonoBehaviour:
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71c1514a6bd24e1e882cebbe1904ce04, type: 3}
m_Name: simfang SDF
m_Name: simfangTMP
m_EditorClassIdentifier:
hashCode: 1985928552
material: {fileID: 7425184593944002063}
@@ -55,6 +55,15 @@ namespace CustomComponent
private int _nextChapterTitleRequestId = 1;
private bool _chapterTitleShownAfterInit;
[Header("章节标题过场")]
[SerializeField] [Min(0f)] private float _chapterTitleDimFadeInDuration = 0.2f;
[SerializeField] [Min(0f)] private float _chapterTitlePreBlackDuration = 0.25f;
[SerializeField] [Min(0f)] private float _chapterTitleTitleFadeInDelay = 0f;
[SerializeField] [Min(0f)] private float _chapterTitleFadeInDuration = 0.3f;
[SerializeField] [Min(0f)] private float _chapterTitleHoldDuration = 1.2f;
[SerializeField] [Min(0f)] private float _chapterTitleFadeOutDuration = 0.3f;
[SerializeField] [Min(0f)] private float _chapterTitleDimFadeOutDuration = 0.2f;
private int _currentChapterId;
private int _currentLineIndex = -1;
private bool _isInitialized;
@@ -572,7 +581,14 @@ namespace CustomComponent
ChapterId = _currentChapterId,
RequestId = requestId,
Title = BuildChapterTitle(_currentChapterId),
Subtitle = subtitle
Subtitle = subtitle,
DimFadeInDuration = _chapterTitleDimFadeInDuration,
PreBlackDuration = _chapterTitlePreBlackDuration,
TitleFadeInDelay = _chapterTitleTitleFadeInDelay,
TitleFadeInDuration = _chapterTitleFadeInDuration,
HoldDuration = _chapterTitleHoldDuration,
TitleFadeOutDuration = _chapterTitleFadeOutDuration,
DimFadeOutDuration = _chapterTitleDimFadeOutDuration
};
int? formSerialId = GameEntry.UI.OpenUIForm(UIFormId.ChapterTitleForm, context);
@@ -1,14 +1,22 @@
using System.Collections;
using System.Collections.Generic;
using DataTable;
using Event;
using GameFramework.DataTable;
using GameFramework.Event;
using GameFramework.Fsm;
using GameFramework.Procedure;
using UnityEngine;
using UI;
using UnityGameFramework.Runtime;
namespace Procedure
{
public class ProcedureMain : ProcedureBase
{
private const int InitialChapterId = 1;
private const int InitialDialogId = 1001;
private const int DialogChapterDivisor = 1000;
private IDataTable<DRDialog> _dtDialog;
public override bool UseNativeDialog => false;
protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
@@ -16,8 +24,104 @@ namespace Procedure
base.OnEnter(procedureOwner);
AIChatEntryRuntime.EnsureOpen();
GameEntry.Dialog.Init(1);
GameEntry.Dialog.StartDialog(1001);
GameEntry.Event.Subscribe(StoryChapterEndedEventArgs.EventId, OnStoryChapterEnded);
GameEntry.Dialog.Init(InitialChapterId);
GameEntry.Dialog.StartDialog(InitialDialogId);
}
protected override void OnLeave(IFsm<IProcedureManager> procedureOwner, bool isShutdown)
{
GameEntry.Event.Unsubscribe(StoryChapterEndedEventArgs.EventId, OnStoryChapterEnded);
base.OnLeave(procedureOwner, isShutdown);
}
private void OnStoryChapterEnded(object sender, GameEventArgs e)
{
if (!(e is StoryChapterEndedEventArgs args))
{
return;
}
int currentChapterId = args.ChapterId > 0
? args.ChapterId
: (GameEntry.Dialog != null ? GameEntry.Dialog.CurrentChapterId : 0);
int nextChapterId = currentChapterId + 1;
if (nextChapterId <= 0)
{
return;
}
if (!TryResolveFirstDialogId(nextChapterId, out int nextDialogId))
{
Log.Info("ProcedureMain chapter switch stopped. No dialog found for chapter '{0}'.",
nextChapterId.ToString());
return;
}
if (GameEntry.Dialog == null)
{
Log.Warning("ProcedureMain chapter switch failed. Dialog component is missing.");
return;
}
if (!GameEntry.Dialog.Init(nextChapterId))
{
Log.Warning("ProcedureMain chapter switch failed. Init chapter '{0}' failed.",
nextChapterId.ToString());
return;
}
if (!GameEntry.Dialog.StartDialog(nextDialogId))
{
Log.Warning("ProcedureMain chapter switch failed. Start dialog '{0}' failed.",
nextDialogId.ToString());
}
}
private bool TryResolveFirstDialogId(int chapterId, out int dialogId)
{
dialogId = 0;
if (chapterId <= 0)
{
return false;
}
if (_dtDialog == null)
{
_dtDialog = GameEntry.DataTable.GetDataTable<DRDialog>();
}
if (_dtDialog == null)
{
Log.Warning("ProcedureMain chapter switch failed. Data table DRDialog is missing.");
return false;
}
DRDialog[] dialogRows = _dtDialog.GetDataRows((a, b) => a.Id.CompareTo(b.Id));
for (int i = 0; i < dialogRows.Length; i++)
{
DRDialog row = dialogRows[i];
if (row == null)
{
continue;
}
if (ParseChapterIdFromDialogId(row.Id) != chapterId)
{
continue;
}
dialogId = row.Id;
return dialogId > 0;
}
return false;
}
private static int ParseChapterIdFromDialogId(int dialogId)
{
return dialogId / DialogChapterDivisor;
}
}
}
@@ -6,5 +6,14 @@ namespace UI
public int RequestId = 0;
public string Title = string.Empty;
public string Subtitle = string.Empty;
// < 0 表示使用 ChapterTitleForm 上的默认配置。
public float DimFadeInDuration = -1f;
public float PreBlackDuration = -1f;
public float TitleFadeInDelay = -1f;
public float TitleFadeInDuration = -1f;
public float HoldDuration = -1f;
public float TitleFadeOutDuration = -1f;
public float DimFadeOutDuration = -1f;
}
}
@@ -10,23 +10,23 @@ namespace UI
public class AIChatForm : UGuiForm
{
[SerializeField] private TMP_Text _returnButtonText;
[SerializeField] private TMP_InputField _inputField;
[SerializeField] private RectTransform _dialogContent;
[SerializeField] private TMP_Text _titleText;
[SerializeField] private ScrollRect _historyScrollRect;
[SerializeField] private AIDialogItem _aiDialogItemPrefab;
[SerializeField] private PlayerDialogItem _playerDialogItemPrefab;
[SerializeField] private HorizonSelectGroup _languageSelectGroup;
[SerializeField] private string _returnButtonNormalText = "<sprite name=\"KEYBOARD_Esc\"> Back";
[SerializeField] private string _returnButtonHoverText = "<sprite name=\"KEYBOARD_Esc\"><u> Back </u>";
private readonly List<Component> _dialogItems = new List<Component>();
@@ -13,14 +13,25 @@ namespace UI
[SerializeField] private Image _dimImage;
[SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _subtitleText;
[SerializeField] private float _dimFadeInDuration = 0.2f;
[SerializeField] private float _preBlackDuration = 0.25f;
[SerializeField] private float _titleFadeInDelay = 0f;
[SerializeField] private float _fadeInDuration = 0.3f;
[SerializeField] private float _holdDuration = 1.2f;
[SerializeField] private float _fadeOutDuration = 0.3f;
[SerializeField] private float _dimFadeOutDuration = 0.2f;
private Coroutine _playCoroutine;
private int _requestId;
private int _chapterId;
private bool _hasPublishedCompletion;
private float _runtimeDimFadeInDuration;
private float _runtimePreBlackDuration;
private float _runtimeTitleFadeInDelay;
private float _runtimeTitleFadeInDuration;
private float _runtimeHoldDuration;
private float _runtimeTitleFadeOutDuration;
private float _runtimeDimFadeOutDuration;
protected override void OnOpen(object userData)
{
@@ -33,7 +44,8 @@ namespace UI
protected override void OnClose(bool isShutdown, object userData)
{
StopPlay();
SetContentAlpha(0f);
SetDimAlpha(0f);
SetTitleAlpha(0f);
if (!isShutdown)
{
PublishCompletionIfNeeded();
@@ -55,6 +67,11 @@ namespace UI
_contentGroup = CreateContentGroup(rootRect);
}
if (_contentGroup != null)
{
_contentGroup.alpha = 1f;
}
RectTransform contentRect = _contentGroup != null && _contentGroup.transform is RectTransform contentTransform
? contentTransform
: rootRect;
@@ -105,6 +122,7 @@ namespace UI
private void ApplyContext(ChapterTitleFormContext context)
{
_hasPublishedCompletion = false;
ResetRuntimeTimings(context);
if (context == null)
{
@@ -157,10 +175,17 @@ namespace UI
private IEnumerator PlayRoutine()
{
SetContentAlpha(0f);
yield return FadeAlpha(0f, 1f, _fadeInDuration);
yield return WaitUnscaled(_holdDuration);
yield return FadeAlpha(1f, 0f, _fadeOutDuration);
SetDimAlpha(0f);
SetTitleAlpha(0f);
yield return FadeDimAlpha(0f, 1f, _runtimeDimFadeInDuration);
yield return WaitUnscaled(_runtimePreBlackDuration);
yield return WaitUnscaled(_runtimeTitleFadeInDelay);
yield return FadeTitleAlpha(0f, 1f, _runtimeTitleFadeInDuration);
yield return WaitUnscaled(_runtimeHoldDuration);
yield return FadeTitleAlpha(1f, 0f, _runtimeTitleFadeOutDuration);
yield return FadeDimAlpha(1f, 0f, _runtimeDimFadeOutDuration);
_playCoroutine = null;
PublishCompletionIfNeeded();
@@ -170,12 +195,12 @@ namespace UI
}
}
private IEnumerator FadeAlpha(float from, float to, float duration)
private IEnumerator FadeDimAlpha(float from, float to, float duration)
{
float safeDuration = Mathf.Max(0f, duration);
if (safeDuration <= 0f)
{
SetContentAlpha(to);
SetDimAlpha(to);
yield break;
}
@@ -184,11 +209,32 @@ namespace UI
{
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / safeDuration);
SetContentAlpha(Mathf.Lerp(from, to, t));
SetDimAlpha(Mathf.Lerp(from, to, t));
yield return null;
}
SetContentAlpha(to);
SetDimAlpha(to);
}
private IEnumerator FadeTitleAlpha(float from, float to, float duration)
{
float safeDuration = Mathf.Max(0f, duration);
if (safeDuration <= 0f)
{
SetTitleAlpha(to);
yield break;
}
float elapsed = 0f;
while (elapsed < safeDuration)
{
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / safeDuration);
SetTitleAlpha(Mathf.Lerp(from, to, t));
yield return null;
}
SetTitleAlpha(to);
}
private static IEnumerator WaitUnscaled(float duration)
@@ -207,14 +253,57 @@ namespace UI
}
}
private void SetContentAlpha(float alpha)
private void SetDimAlpha(float alpha)
{
if (_contentGroup == null)
if (_dimImage == null)
{
return;
}
_contentGroup.alpha = Mathf.Clamp01(alpha);
Color color = _dimImage.color;
color.a = Mathf.Clamp01(alpha);
_dimImage.color = color;
}
private void SetTitleAlpha(float alpha)
{
float clampedAlpha = Mathf.Clamp01(alpha);
SetTextAlpha(_titleText, clampedAlpha);
SetTextAlpha(_subtitleText, clampedAlpha);
}
private static void SetTextAlpha(TMP_Text text, float alpha)
{
if (text == null)
{
return;
}
Color color = text.color;
color.a = alpha;
text.color = color;
}
private void ResetRuntimeTimings(ChapterTitleFormContext context)
{
_runtimeDimFadeInDuration = ResolveDuration(context != null ? context.DimFadeInDuration : -1f,
_dimFadeInDuration);
_runtimePreBlackDuration = ResolveDuration(context != null ? context.PreBlackDuration : -1f,
_preBlackDuration);
_runtimeTitleFadeInDelay = ResolveDuration(context != null ? context.TitleFadeInDelay : -1f,
_titleFadeInDelay);
_runtimeTitleFadeInDuration = ResolveDuration(context != null ? context.TitleFadeInDuration : -1f,
_fadeInDuration);
_runtimeHoldDuration = ResolveDuration(context != null ? context.HoldDuration : -1f, _holdDuration);
_runtimeTitleFadeOutDuration = ResolveDuration(context != null ? context.TitleFadeOutDuration : -1f,
_fadeOutDuration);
_runtimeDimFadeOutDuration = ResolveDuration(context != null ? context.DimFadeOutDuration : -1f,
_dimFadeOutDuration);
}
private static float ResolveDuration(float overrideDuration, float fallbackDuration)
{
return overrideDuration >= 0f ? overrideDuration : Mathf.Max(0f, fallbackDuration);
}
private void PublishCompletionIfNeeded()
@@ -14,5 +14,5 @@ MonoBehaviour:
m_EditorClassIdentifier:
_enabled: 1
_triggerType: 0
_triggerId: 1005
_chapterId: 2
_triggerId: 1006
_chapterId: 1
@@ -15,4 +15,4 @@ MonoBehaviour:
_enabled: 1
_triggerType: 0
_triggerId: 2006
_chapterId: 3
_chapterId: 2
@@ -15,4 +15,4 @@ MonoBehaviour:
_enabled: 1
_triggerType: 0
_triggerId: 3005
_chapterId: 4
_chapterId: 3
@@ -15,4 +15,4 @@ MonoBehaviour:
_enabled: 1
_triggerType: 0
_triggerId: 4004
_chapterId: 0
_chapterId: 4
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 77968dfed7b61334db617d490bb05477
guid: 0d041269ac2f63d47bc5f189d90dc73d
TextureImporter:
internalIDToNameTable: []
externalObjects: {}