Merge branch 'feature/章节管理' into feature/章节管理合入

This commit is contained in:
2026-04-28 15:53:30 +08:00
75 changed files with 1510 additions and 103 deletions
@@ -12,11 +12,11 @@ namespace AibisDream
#region
[YarnCommand("NextYarn")]
public static void NextYarn()
public static void NextYarn(string exitName = null)
{
EnumEventSystem.Global.Send(EventEnum.NextYarn);
StorageSystem.Instance.ClearLocal();
DialogController.Instance.StartCoroutine(GameManager.Instance.NextSceneSo());
DialogController.Instance.StartCoroutine(GameManager.Instance.NextSceneSo(exitName));
}
[YarnCommand("OpenEndMenu")]
+21 -8
View File
@@ -24,9 +24,14 @@ namespace AibisDream
cacheChapter = ParseChapterTitle(saveFilePath);
}
// 优先从 GameManager 获取全量章节并按 displayOrder 排序
var allChapters = GameManager.Instance?.GetAllSceneSos();
var sourceList = allChapters != null
? allChapters.OrderBy(so => so.displayOrder).ToList()
: ChapterData.chapterList;
// 拼接章节列表
var chapterList = ChapterData.chapterList
var chapterList = sourceList
.Where(item => ChapterData.unlockedChapterList.Contains(item.name))
.Select(chapterSo => new ChapterVo
{
@@ -98,14 +103,22 @@ namespace AibisDream
private void LoadChapterList()
{
chapterList = new List<TalkSceneSO>();
var curChapter = firstChapter;
do
var all = GameManager.Instance?.GetAllSceneSos();
if (all != null)
{
chapterList.Add(curChapter);
curChapter = curChapter.nextScene;
} while (curChapter != null && !chapterList.Contains(curChapter));
chapterList = all.OrderBy(so => so.displayOrder).ToList();
}
else
{
chapterList = new List<TalkSceneSO>();
var curChapter = firstChapter;
do
{
chapterList.Add(curChapter);
curChapter = curChapter.GetNextScene();
} while (curChapter != null && !chapterList.Contains(curChapter));
}
}
private void LoadUnlockChapters()
+7 -4
View File
@@ -237,11 +237,12 @@ namespace AibisDream
#endregion
public IEnumerator NextSceneSo()
public IEnumerator NextSceneSo(string exitName = null)
{
if (_currentTalkSceneSo.Value && _currentTalkSceneSo.Value.nextScene)
var next = _currentTalkSceneSo.Value?.GetNextScene(exitName);
if (next != null)
{
_currentTalkSceneSo.Value = _currentTalkSceneSo.Value.nextScene;
_currentTalkSceneSo.Value = next;
ChapterController.Instance.UnlockChapter(_currentTalkSceneSo.Value);
yield return UIManager.Instance.GetPanel<PlayToolPanel>().FadeInAsync();
yield return SceneLoader.Instance.LoadSceneAsync(_currentTalkSceneSo.Value.firstSceneName);
@@ -249,11 +250,13 @@ namespace AibisDream
}
else
{
Debug.Log($"没有下个场景了 (exitName: {exitName})");
yield return null;
Debug.Log("没有下个场景了");
}
}
public TalkSceneSO[] GetAllSceneSos() => _totalSceneSos;
public void SetSceneSoByName(string soName)
{
_currentTalkSceneSo.Value = Array.Find(_totalSceneSos, so => so.name == soName);
+40 -3
View File
@@ -1,15 +1,29 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Yarn.Unity;
namespace AibisDream
{
[Serializable]
public class SceneExit
{
[Tooltip("出口名称,用于Yarn命令指定跳转目标,如 good_end / bad_end / default")]
public string exitName;
public TalkSceneSO targetScene;
}
/// <summary>
/// 章节类型数据
/// </summary>
[CreateAssetMenu(menuName = "Game Scene/TalkSceneSO")]
public class TalkSceneSO : ScriptableObject
{
public TalkSceneSO nextScene;
{
private const string DEFAULT_EXIT_NAME = "default";
public List<SceneExit> exits = new();
public int displayOrder;
public YarnProject yarnProject;
@@ -23,6 +37,29 @@ namespace AibisDream
public string chapter;
#endregion
#region 使
[HideInInspector] public Vector2 graphPosition;
public Color nodeColor = new(0.85f, 0.45f, 0.45f);
#endregion
public TalkSceneSO GetNextScene(string exitName = null)
{
if (exits == null || exits.Count == 0)
return null;
if (string.IsNullOrEmpty(exitName))
exitName = DEFAULT_EXIT_NAME;
foreach (var exit in exits)
{
if (exit.exitName == exitName)
return exit.targetScene;
}
return null;
}
}
}