Story流程+本地化

This commit is contained in:
SoulliesOfficial
2026-07-24 17:56:30 -04:00
parent b0e0a7d5aa
commit de70870682
250 changed files with 5719 additions and 272966 deletions

View File

@@ -70,13 +70,13 @@ namespace Ichni.Menu
public void SetBeatmapInfo(BeatmapSave beatmapSave)
{
accuracyText.text = $"{beatmapSave.accuracy * 100:F2}%";
if (!beatmapSave.isAllPerfect)
{
fullComboMark.gameObject.SetActive(beatmapSave.isFullCombo);
}
allPerfectMark.gameObject.SetActive(beatmapSave.isAllPerfect);
// 两种成绩徽记互斥显示All Perfect 的优先级高于 Full Combo。
// 必须每次都显式设置两个对象;仅在非 All Perfect 时更新 Full Combo 会让 Prefab
// 初始状态或上一次选择谱面的显示状态残留,造成首次进入时同时出现两个徽记。
bool showAllPerfect = beatmapSave.isAllPerfect;
fullComboMark.gameObject.SetActive(!showAllPerfect && beatmapSave.isFullCombo);
allPerfectMark.gameObject.SetActive(showAllPerfect);
}
}
}
}

View File

@@ -3,6 +3,7 @@ using Ichni.RhythmGame;
using Ichni.Story;
using Ichni.UI;
using SLSUtilities.WwiseAssistance;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UnityEngine.UI.Extensions;
@@ -12,6 +13,9 @@ namespace Ichni.Menu
public partial class SongSelectionUIPage : UIPageBase
{
public Button backButton;
[Tooltip("从选曲页进入当前章节剧情树的按钮。会优先定位当前选中歌曲对应的 SongBlock未找到时显示剧情开头。")]
public Button enterStoryButton;
public Gradient2 backgroundFrames;
public float framePositionOffset = -1;
@@ -44,21 +48,48 @@ namespace Ichni.Menu
MenuInputManager.OnMoveDown += songListController.GoToNextTab;
};
backButton.onClick.AddListener(() =>
{
FadeOut();
SongSelectionManager.instance.StopPreviewSong();
backButton.onClick.AddListener(ReturnToChapterSelection);
// 仅当本次选曲由剧情 SongBlock 发起时返回剧情页;普通选曲保持原有的章节选择返回逻辑。
if (StoryManager.instance != null && StoryManager.instance.TryReturnFromSongSelection())
StoryManager.instance.storyUIPage.FadeIn();
else
MenuManager.instance.chapterSelectionUIPage.FadeIn();
});
if (enterStoryButton != null)
enterStoryButton.onClick.AddListener(OpenStoryForSelectedSong);
songInfoUI.SetUp();
}
private void OnDestroy()
{
backButton.onClick.RemoveListener(ReturnToChapterSelection);
if (enterStoryButton != null)
enterStoryButton.onClick.RemoveListener(OpenStoryForSelectedSong);
}
/// <summary>
/// 选曲页的全局返回语义固定为回到章节选择页。
/// 即使本次页面最初由 Story SongBlock 打开,也不再把 Back 视为“返回剧情树”;
/// 玩家需要使用专门的 <see cref="enterStoryButton"/> 进入剧情。
/// </summary>
private void ReturnToChapterSelection()
{
FadeOut();
SongSelectionManager.instance.StopPreviewSong();
// Story SongBlock 入口上下文只服务于一次“进入游戏后返回剧情”的流程。
// 玩家主动离开选曲页时必须清除它,避免之后普通选曲误继承旧的目标歌曲与返回目的地。
InformationTransistor.instance?.storySongEntryContext?.Clear();
MenuManager.instance.chapterSelectionUIPage.FadeIn();
}
/// <summary>
/// 从选曲页打开当前章节的剧情树。若当前歌曲在 StoryData 中存在对应 SongBlock
/// StoryManager 会把视口定位到该 Block未选中歌曲或没有对应 Block 时则显示剧情开头。
/// </summary>
private void OpenStoryForSelectedSong()
{
ChapterSelectionUnit chapter = ChapterSelectionManager.instance?.currentChapter;
StoryManager.instance?.TryOpenStoryForSong(chapter, selectedSong);
}
private void Start()
{
Sequence framesSeq = DOTween.Sequence();