Files
ichni_Official/Assets/Scripts/NewStorySystem/UI/DialogueHistoryPage.cs
SoulliesOfficial 810d019619 剧情+对话完善
2026-07-21 15:24:42 -04:00

88 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}