剧情+对话完善

This commit is contained in:
SoulliesOfficial
2026-07-21 15:24:42 -04:00
parent 8f230831e9
commit 810d019619
161 changed files with 7271 additions and 1893 deletions

View File

@@ -0,0 +1,87 @@
using System.Collections.Generic;
using Ichni.Story.Dialogue;
using UnityEngine;
using UnityEngine.UI;
namespace Ichni.Story.UI
{
/// <summary>
/// 对话记录覆盖面板。
/// <para>它不是独立 UIPage打开时覆盖在 DialogUIPage 上方,并由全屏 Raycast Target 阻断底层输入;
/// 关闭后仅恢复对话画面,不推进 Yarn 对话。</para>
/// </summary>
public class DialogueHistoryPage : MonoBehaviour
{
[Header("References")]
[Tooltip("覆盖全屏的 CanvasGroup。根物体应位于 DialogCanvas 顶层,并包含可接收 Raycast 的全屏透明 Image。")]
[SerializeField] private CanvasGroup canvasGroup;
[SerializeField] private ScrollRect scrollRect;
[SerializeField] private RectTransform entryContainer;
[SerializeField] private DialogueHistoryEntryView entryPrefab;
[SerializeField] private Button closeButton;
/// <summary>当前覆盖层是否正在显示并拦截 DialogUIPage 输入。</summary>
public bool IsOpen => _isOpen;
private readonly List<DialogueHistoryEntryView> _spawnedEntries = new();
private bool _isOpen;
private void Awake()
{
if (closeButton != null)
closeButton.onClick.AddListener(Close);
SetVisible(false);
}
private void OnDestroy()
{
if (closeButton != null)
closeButton.onClick.RemoveListener(Close);
}
/// <summary>以当前一次 TextBlock 对话的内存记录刷新并打开覆盖面板。</summary>
public void Open(IReadOnlyList<DialogueHistoryEntry> entries)
{
RebuildEntries(entries);
SetVisible(true);
Canvas.ForceUpdateCanvases();
// 记录按时间从上到下排列;打开后停在最早一条,玩家可向下浏览最新内容。
if (scrollRect != null)
scrollRect.verticalNormalizedPosition = 1f;
}
/// <summary>关闭覆盖面板,不修改当前 Yarn 进度或选项状态。</summary>
public void Close() => SetVisible(false);
private void RebuildEntries(IReadOnlyList<DialogueHistoryEntry> entries)
{
foreach (DialogueHistoryEntryView view in _spawnedEntries)
if (view != null)
Destroy(view.gameObject);
_spawnedEntries.Clear();
if (entries == null || entryPrefab == null || entryContainer == null)
return;
foreach (DialogueHistoryEntry entry in entries)
{
DialogueHistoryEntryView view = Instantiate(entryPrefab, entryContainer);
view.SetUp(entry);
_spawnedEntries.Add(view);
}
}
private void SetVisible(bool visible)
{
_isOpen = visible;
if (canvasGroup == null)
return;
canvasGroup.alpha = visible ? 1f : 0f;
canvasGroup.interactable = visible;
canvasGroup.blocksRaycasts = visible;
}
}
}