剧情+对话完善
This commit is contained in:
87
Assets/Scripts/NewStorySystem/UI/DialogueHistoryPage.cs
Normal file
87
Assets/Scripts/NewStorySystem/UI/DialogueHistoryPage.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user