using System.Collections.Generic; using System.IO; using System.Linq; using AibisDream.Kit; using AibisDream.Utility; using UnityEngine; namespace AibisDream { public class ChapterController : Singleton { private ChapterData ChapterData => GlobalDataContainer.Instance.GetData(); /// /// 获取章节列表用于显示 /// /// 章节列表 public List GetChapterList() { // 获取存档并提取章节信息 var cacheChapter = string.Empty; if (ChapterData.TryGetSaveFilePath(out var saveFilePath)) { cacheChapter = ParseChapterTitle(saveFilePath); } var sourceList = GameManager.Instance.GetAllSceneSos(); // 拼接章节列表 var chapterList = sourceList .Where(item => ChapterData.unlockedChapterList.Contains(item.name)) .Select(chapterSo => new ChapterVo { chapterSo = chapterSo, title = chapterSo.title, chapter = chapterSo.chapter, desc = chapterSo.description, pic = chapterSo.coverPic, hasSaveFile = cacheChapter == chapterSo.name }) .ToList(); return chapterList; } private static string ParseChapterTitle(string filePath) { var fileName = Path.GetFileNameWithoutExtension(filePath); var parts = fileName.Split('_'); // 文件名格式: yyyyMMdd-HHmmss_{sceneSoName}_{gameStage} // sceneSoName 可能包含下划线,但时间戳(第0段)和游戏阶段(最后1段)不会 if (parts.Length < 3) { Debug.LogWarning($"存档文件名格式异常: {fileName}"); return string.Empty; } var sceneSoName = string.Join("_", parts, 1, parts.Length - 2); Debug.Log($"ParseChapterTitle: 从 {fileName} 解析出章节名 = {sceneSoName}"); return sceneSoName; } public void StartWithChapter(ChapterVo chapterVo) { GameManager.Instance.StartWithLevel(chapterVo.chapterSo); } public void StartWithSaveFile() { // 获取当前存档 if (!ChapterData.TryGetSaveFilePath(out var saveFilePath)) { Debug.LogError("未找到存档"); } else { GameManager.Instance.StartWithSaveFile(saveFilePath); } } public void UnlockChapter(TalkSceneSO chapterSo) { if (chapterSo.name == "GeneralEnd") { return; } if (!ChapterData.unlockedChapterList.Contains(chapterSo.name)) { ChapterData.unlockedChapterList.Add(chapterSo.name); ChapterData.SaveUnloadChapters(); } } } [GlobalData] public class ChapterData { public List unlockedChapterList; public ChapterData() { Directory.CreateDirectory(ConstRef.SaveFilePath); LoadUnlockChapters(); } private void LoadUnlockChapters() { unlockedChapterList = File.Exists(ConstRef.ChapterProgressPath) ? JsonUtil.ReadBeanArray(ConstRef.ChapterProgressPath).ToList() : new List { GameManager.Instance.firstTalkSo.name }; } public void SaveUnloadChapters() { JsonUtil.SaveArray(unlockedChapterList.ToArray(), ConstRef.ChapterProgressPath); } public bool TryGetSaveFilePath(out string saveFilePath) { var files = Directory.GetFiles(ConstRef.SaveFilePath, "*.json") .OrderByDescending(fileName => fileName) .ToArray(); if (files.Length <= 0) { saveFilePath = string.Empty; return false; } saveFilePath = files[0]; return true; } } public struct ChapterVo { public string title; public string chapter; public string desc; public Sprite pic; public bool hasSaveFile; public TalkSceneSO chapterSo; } }