存档重构,游戏内容解锁机制;教程完善(未完成)

This commit is contained in:
SoulliesOfficial
2026-07-18 16:51:18 -04:00
parent d48ef1e65e
commit dda354ebb9
123 changed files with 4032 additions and 558 deletions

View File

@@ -66,6 +66,7 @@ namespace Ichni
CoreServices.TimeProvider = this;
timeDurations = new List<TimeDurationSubmodule>();
playingRecorder = new PlayingRecorder();
playingRecorder.Initialize();
updateScheduler = new ElementUpdateScheduler();
CoreServices.UpdateScheduler = updateScheduler;
}
@@ -89,17 +90,47 @@ namespace Ichni
public partial class GameManager
{
/// <summary>
/// 将当前演奏结果写入独立的游戏记录存档。
/// <para>由 SongPlayer 在实际歌曲结束后、打开 Summary 前调用。</para>
/// <para>剧情树、选项和 Yarn 变量仍由 <see cref="StorySaveModule"/> 单独管理。</para>
/// 当前 Difficulty 的 Chart Revision 会一并传入,从而在谱面改版时只清除不可比较的单谱面成绩。
/// </summary>
public bool SaveCurrentPlayRecord()
{
if (GameSaveManager.instance == null || GameSaveManager.instance.SongSaveModule == null)
{
Debug.LogWarning("Cannot save play record because SongSaveModule is not initialized.");
return false;
}
if (InformationTransistor.instance == null ||
InformationTransistor.instance.song == null ||
InformationTransistor.instance.difficulty == null)
{
Debug.LogWarning("Cannot save play record because the selected song or difficulty is missing.");
return false;
}
return GameSaveManager.instance.SongSaveModule.RecordPlayResult(
InformationTransistor.instance.song.songName,
InformationTransistor.instance.difficulty.saveDifficultyId,
InformationTransistor.instance.difficulty.GetChartRevision(),
playingRecorder);
}
public static void RestartGame()
{
// 保留 InformationTransistor 中的歌曲和返回目标,使教程与普通歌曲的重开都回到正确页面。
SceneManager.LoadScene("GameScene");
Time.timeScale = 1f; // 确保重启时时间缩放恢复正常
}
public static void ReturnToMenu()
{
//InformationTransistor.instance.isReturnedFromGame = true;
SceneManager.LoadScene("MenuScene");
Time.timeScale = 1f; // 确保返回时时间缩放恢复正常
// 返回目标已在进入 GameScene 时写入 InformationTransistor这里不再写互斥布尔值。
SceneManager.LoadScene("MenuScene");
}
}
}
}

View File

@@ -4,6 +4,11 @@ using UnityEngine;
namespace Ichni.RhythmGame
{
/// <summary>
/// 单次演奏的运行时判定记录。
/// 本类随 GameScene 重建,只负责本局结算;长期最佳成绩由 SongSaveModule 写入 ES3
/// 因此不要把此对象直接当作存档模型使用。
/// </summary>
public class PlayingRecorder
{
public int perfectCount;
@@ -17,13 +22,28 @@ namespace Ichni.RhythmGame
public int currentCombo;
public int maxCombo;
/// <summary>本局判定偏差图数据,仅供当前 Summary 使用,不写入存档。</summary>
public List<float> resultData = new List<float>();
public bool isFullCombo;
public bool isAllPerfect;
/// <summary>
/// 在进入一局新演奏时重置全部瞬时状态。
/// 初始化为 100% / FC / AP 是为了让首个非 Perfect 判定能正确打破对应状态;
/// 无有效判定的空局不会被 SongSaveModule 写入成绩。
/// </summary>
public void Initialize()
{
if (resultData == null)
{
resultData = new List<float>();
}
else
{
resultData.Clear();
}
perfectCount = 0;
goodCount = 0;
badCount = 0;
@@ -105,4 +125,4 @@ namespace Ichni.RhythmGame
GameManager.Instance.gameUICanvas.UpdateCombo(currentCombo);
}
}
}
}

View File

@@ -170,7 +170,14 @@ namespace Ichni
if (in_type == AkCallbackType.AK_MusicSyncExit)
{
if (isFinished)
{
return;
}
isFinished = true;
// 先持久化再展示结算,确保玩家即使在 Summary 停留期间退出也不会丢失本局成绩。
GameManager.Instance.SaveCurrentPlayRecord();
GameManager.Instance.summaryPageCanvas.SetUpSummary();
GameManager.Instance.summaryPageCanvas.FadeIn();
}
@@ -184,4 +191,4 @@ namespace Ichni
return segmentInfo.iCurrentPosition;
}
}
}
}