Files
aibis-dream/Assets/Scripts/UI/Terminal/InGameTerminalPanel.cs
T
dingyuntian 0a1adf1558 fix: 部分QA问题处理
1. 返回主菜单闪烁
2. 对话隐藏
3. 历史记录宽度调整
2026-07-26 16:36:51 +08:00

264 lines
7.0 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace AibisDream.UI
{
public enum InGameTerminalPage
{
None,
Setting,
Record,
}
/// <summary>
/// 局内终端 Panel 壳:管理 Setting / Record 两个 Page。
/// Setting / Record 需在场景中分别挂独立的 Prefab 实例,并在 Inspector 中绑定。
/// </summary>
public class InGameTerminalPanel : MonoBehaviour, IUIPanel, ITerminalPanelHost
{
[SerializeField] private TerminalHeaderView header;
[SerializeField] private TerminalSettingPanel settingPage;
[SerializeField] private TerminalRecordPanel recordPage;
private readonly Stack<InGameTerminalPage> _backStack = new();
private InGameTerminalPage _currentPage = InGameTerminalPage.None;
private bool _pausedByPanel;
private bool _isReturningToMainMenu;
public bool IsOpen => gameObject.activeSelf && _currentPage != InGameTerminalPage.None;
public bool IsCloseable => false;
public InGameTerminalPage CurrentPage => _currentPage;
public bool IsInGameContext => true;
public void Initialize()
{
var root = transform;
settingPage ??= root.GetComponentInChildren<TerminalSettingPanel>(true);
recordPage ??= root.GetComponentInChildren<TerminalRecordPanel>(true);
settingPage?.SetOwner(this);
recordPage?.SetOwner(this);
if (!HasRequiredPages())
{
Debug.LogError("[InGameTerminalPanel] Missing required pages. Assign TerminalSettingPanel and TerminalRecordPanel on the in-game shell.");
}
Close();
}
public bool HasRequiredPages()
{
return settingPage != null && recordPage != null;
}
public void Show()
{
Open(InGameTerminalPage.Setting);
}
public void Hide()
{
Close();
}
public void Open(InGameTerminalPage page)
{
if (!HasRequiredPages() || page == InGameTerminalPage.None)
{
return;
}
_isReturningToMainMenu = false;
if (!IsOpen)
{
_backStack.Clear();
}
gameObject.SetActive(true);
PauseIfNeeded();
SwitchTo(page, pushCurrent: false);
}
public void SwitchTo(InGameTerminalPage page, bool pushCurrent = true)
{
if (page == InGameTerminalPage.None || page == _currentPage)
{
return;
}
if (pushCurrent && _currentPage != InGameTerminalPage.None)
{
_backStack.Push(_currentPage);
}
var previous = _currentPage;
_currentPage = page;
if (previous == InGameTerminalPage.None)
{
ShowPage(_currentPage);
return;
}
HidePage(previous, () => ShowPage(_currentPage));
}
public void Back()
{
if (_backStack.Count > 0)
{
var previous = _backStack.Pop();
var current = _currentPage;
_currentPage = previous;
HidePage(current, () => ShowPage(_currentPage));
return;
}
Close();
}
public bool HandleEscape()
{
if (!IsOpen)
{
return false;
}
if (_isReturningToMainMenu)
{
return true;
}
Back();
return true;
}
public void Close()
{
if (_isReturningToMainMenu)
{
return;
}
Close(restoreAmb: true);
}
public void Close(bool restoreAmb)
{
HideAllPages();
_backStack.Clear();
_currentPage = InGameTerminalPage.None;
ContinueIfPaused(restoreAmb);
gameObject.SetActive(false);
}
public void CloseToMainMenu()
{
if (_isReturningToMainMenu || GameManager.Instance == null)
{
return;
}
if (GameManager.Instance.TryReturnToMainMenu())
{
// Keep this full-screen panel visible while the global transition
// covers the gameplay behind it. GameManager closes it only after
// the screen is fully covered.
_isReturningToMainMenu = true;
}
}
public void CloseForSessionEnd()
{
HideAllPages();
_backStack.Clear();
_currentPage = InGameTerminalPage.None;
if (_pausedByPanel)
{
TerminalUIAudio.NotifyPauseMenuAmbExit(restorePrevious: false);
_pausedByPanel = false;
}
_isReturningToMainMenu = false;
gameObject.SetActive(false);
}
public void SetHeader(string title, string status = "")
{
header?.SetText(title, status);
}
public void AppendDialogLine(LineInfo lineInfo)
{
recordPage?.AppendDialogLine(lineInfo);
}
public void ClearDialog()
{
recordPage?.ClearDialog();
}
private void PauseIfNeeded()
{
if (GameManager.Instance == null || !GameManager.Session.CanPause || _pausedByPanel)
{
return;
}
GameManager.Instance.TryPause();
TerminalUIAudio.NotifyPauseMenuAmbEnter();
_pausedByPanel = true;
}
private void ContinueIfPaused(bool restoreAmb = true)
{
if (!_pausedByPanel)
{
return;
}
GameManager.Instance.TryResume();
TerminalUIAudio.NotifyPauseMenuAmbExit(restoreAmb);
_pausedByPanel = false;
}
private void ShowPage(InGameTerminalPage page)
{
switch (page)
{
case InGameTerminalPage.Setting:
settingPage?.Show();
break;
case InGameTerminalPage.Record:
recordPage?.Show();
break;
}
}
private void HidePage(InGameTerminalPage page, Action onComplete = null)
{
switch (page)
{
case InGameTerminalPage.Setting:
settingPage?.Hide(onComplete);
break;
case InGameTerminalPage.Record:
recordPage?.Hide(onComplete);
break;
default:
onComplete?.Invoke();
break;
}
}
private void HideAllPages()
{
settingPage?.Hide();
recordPage?.Hide();
}
}
}