Files
ichni_Official/Assets/Scripts/Menu/MenuManager.cs

157 lines
6.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;
using System.Collections;
using System.Collections.Generic;
using AK.Wwise;
using Ichni.Menu;
using Ichni.Menu.UI;
using Ichni.Story;
using Ichni.Story.UI;
using Ichni.UI;
using Sirenix.OdinInspector;
using SLSUtilities.WwiseAssistance;
using UniRx;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
namespace Ichni
{
public partial class MenuManager : MonoBehaviour
{
public static MenuManager instance;
public StartUIPage startUIPage;
public LoginPage loginPage;
public ChapterSelectionUIPage chapterSelectionUIPage;
public StoryUIPage storyUIPage;
public SelectionBoxUIPage selectionBoxUIPage;
// dialogUIPage 已随旧对话系统移除;阶段 3 将接入新的 VN 对话页面引用
public SongSelectionUIPage songSelectionUIPage;
public TransitionUIPage transitionUIPage;
public SettingsUIPage settingsUIPage;
public List<string> languageList;
public List<string> displayLanguageList;
}
public partial class MenuManager
{
AsyncOperation asyncOperation;
public bool isEnteringGame;
/// <summary>
/// 当前 MenuScene 是否已经完成 GameScene 预加载且尚未处于切场中。
/// TutorialFlowController 在写入“已处理”剧情变量前使用此状态进行最后一次启动前检查。
/// </summary>
public bool CanBeginGame => !isEnteringGame && asyncOperation != null;
private void Awake()
{
instance = this;
}
private void Start()
{
isEnteringGame = false;
InformationTransistor information = InformationTransistor.instance;
MenuReturnDestination returnDestination = information != null
? information.menuReturnDestination
: MenuReturnDestination.None;
if (returnDestination == MenuReturnDestination.SongSelection &&
information != null && information.chapter != null &&
information.song != null && information.difficulty != null)
{
startUIPage.mainCanvasGroup.gameObject.SetActive(false);
ChapterSelectionManager.instance.currentChapter =
information.chapter;
AudioManager.SetSwitch(ChapterSelectionManager.instance.currentChapter.chapterSwitch);
MenuInformationRecorder.instance.songSelectionRecords[
ChapterSelectionManager.instance.currentChapter] =
new SongSelectionRecord(information.song, information.difficulty);
songSelectionUIPage.FadeIn();
}
else if (returnDestination == MenuReturnDestination.Story &&
information != null && information.chapter != null)
{
startUIPage.mainCanvasGroup.gameObject.SetActive(false);
ChapterSelectionManager.instance.currentChapter = information.chapter;
AudioManager.SetSwitch(ChapterSelectionManager.instance.currentChapter.chapterSwitch);
// MenuScene 会在教程游玩后重新创建,必须显式重建章节故事树,
// 不能依赖旧场景中残留的 Block 实例。
StoryManager.instance?.OpenChapter(ChapterSelectionManager.instance.currentChapter.chapterIndex);
storyUIPage.FadeIn();
}
// 返回目标是一次性运行态信息。无论是否能恢复页面,都不能让它在下次重进菜单时重复生效。
information?.ClearMenuReturnDestination();
Application.targetFrameRate = SettingsManager.instance.gameSettings.targetFrame;
asyncOperation = SceneManager.LoadSceneAsync("GameScene");
asyncOperation.allowSceneActivation = false;
}
}
public partial class MenuManager
{
public void EnterGame()
{
EnterGame(MenuReturnDestination.SongSelection);
}
/// <summary>
/// 激活已预加载的 GameScene并写入唯一的菜单返回目标。
/// 普通选曲使用 <see cref="MenuReturnDestination.SongSelection"/>,教程使用
/// <see cref="MenuReturnDestination.Story"/>。
/// </summary>
public void EnterGame(MenuReturnDestination returnDestination)
{
InformationTransistor.instance?.SetMenuReturnDestination(returnDestination);
EnterGameScene();
}
/// <summary>
/// 为 TutorialBlock 等非选曲入口准备上下文并播放通用转场。
/// 运行成功后会返回 true返回 false 时不会修改剧情变量或存档,调用方应保留原状。
/// </summary>
public bool TryBeginGame(ChapterSelectionUnit chapter, SongItemData song,
DifficultyData difficulty, MenuReturnDestination returnDestination, UIPageBase sourcePage)
{
if (!CanBeginGame)
{
Debug.LogWarning("[MenuManager] GameScene 未完成预加载或菜单已在切换,忽略启动请求。");
return false;
}
if (InformationTransistor.instance == null ||
!InformationTransistor.instance.PrepareGameLaunch(chapter, song, difficulty, returnDestination))
{
return false;
}
isEnteringGame = true;
sourcePage?.FadeOut();
transitionUIPage?.FadeIn();
AudioManager.Post(AK.EVENTS.ENTERTOGAME);
Observable.Timer(TimeSpan.FromSeconds(0.6f)).Subscribe(_ => EnterGameScene());
return true;
}
public void EnterGameScene()
{
if (asyncOperation == null)
{
Debug.LogError("[MenuManager] GameScene 尚未完成预加载,无法进入游戏。");
isEnteringGame = false;
return;
}
MenuInputManager.instance?.gameInput?.Menu.Disable();
asyncOperation.allowSceneActivation = true;
}
}
}