超大量的更新 修复很多问题,gameplay特效初步

This commit is contained in:
FloatGaming
2026-02-14 23:46:20 +08:00
parent ef8eb67259
commit 3a7a0b4669
360 changed files with 85670 additions and 4144 deletions
@@ -9,22 +9,25 @@ using UnityEditor;
public class settlementController : MonoBehaviour
{
[Header("管理器与基础引用")]
[Header("Inspector")]
[SerializeField] private BeatmapManager bmm;
[SerializeField] private ScoreManager sm;
public GameManager gm;
private SongData thisSong_so;
private int maxScore_sum = 2000000;
[Header("1000000")]
public int _1000000 = 1000000;
[Header("song image")]
[SerializeField] private Image thisSong_backPic;
[Header("跳转控制按钮")]
[Header("Inspector")]
public Button exit_toSelectSongs;
public Button replay_thisGame;
public Button display_rankList;
public Button share_toSocialMedia;
[Header("文本与进度显示")]
[Header("Text And Progress")]
public Text songName_Text;
[Tooltip("当前关卡的进度百分比")]
[Tooltip("Documentation text normalized.")]
public Text thisLevel_currentPercentage_Text;
public Text finalScore_Text;
public Text pmScoreSum_Text;
@@ -33,26 +36,26 @@ public class settlementController : MonoBehaviour
public Image thisLevel_progressBar_Image;
[Header("准确度权重算法")]
[Header("Accuracy Weights")]
public float perfect_weight = 1f;
public float great_weight = 0.6666667f;
public float good_weight = 0.333333f;
public float miss_weight = 0;
[Header("结算奖励信息")]
[Header("Inspector")]
public Text reward_playerEXP_Text;
public Text reward_money_Text;
public Text reward_idolEXP_bottle_Text;
[Header("队伍展示")]
[Header("Inspector")]
public loadSettlementTeamPrefab settlementTeamLoader;
public Image mvp_hero_hd_image;
[Header("结算获得金钱")]
[Header("Inspector")]
[SerializeField] private long moneyToGive_thisLevel;
// 得到评分统计
[Header("音符判定统计")]
// Documentation text normalized.
[Header("Inspector")]
public Text perfectHitCount_Text;
public Text perfectHitPercent_Text;
public Image perfect_barFill_Image;
@@ -76,35 +79,36 @@ public class settlementController : MonoBehaviour
public Text lateHitCount_Text;
public Text avgOffset_Text;
[Header("结算音频控制")]
[Tooltip("结算界面背景音乐,播放结算流程")]
[Header("Inspector")]
[Tooltip("Settlement background music clip used during the settlement flow.")]
public AudioSource settlementAudioSource;
[Tooltip("游戏背景音乐(通常是原游戏曲目)")]
[Tooltip("Original gameplay music source (usually the chart song). ")]
public AudioSource oriGameMusicSource;
[Tooltip("音频混音器,用于低通滤波等效果")]
[Tooltip("Documentation text normalized.")]
public AudioMixer gameMusicMixer;
[Tooltip("音频混音器中的低通滤波参数名")]
[Tooltip("Documentation text normalized.")]
public string lowpassParamName = "inGameMusic_lowpass";
[Tooltip("低通滤波器渐变持续时间(秒)")]
[Tooltip("Duration of lowpass transition in seconds.")]
public float lowpassFadeDuration = 2f;
[Tooltip("结算界面 CanvasGroup,用于淡入效果")]
[Tooltip("Settlement CanvasGroup used for fade-in.")]
public CanvasGroup settlementCanvasGroup;
[Header("结算控制组件")]
[Tooltip("结算控制管理器")]
[Header("Inspector")]
[Tooltip("Settlement control manager object.")]
public GameObject cdm;
private Coroutine musicTransitionCoroutine;
private Coroutine canvasFadeCoroutine;
private bool settlementUiInitialized = false;
private void Awake()
{
// 设置按钮监听
// Documentation text normalized.
if (replay_thisGame != null)
{
replay_thisGame.onClick.AddListener(OnReplayButtonClicked);
@@ -115,7 +119,7 @@ public class settlementController : MonoBehaviour
exit_toSelectSongs.onClick.AddListener(OnExitButtonClicked);
}
// 确保 CDM 对象在开始时处于关闭状态
// Documentation text normalized.
if (cdm != null)
{
cdm.SetActive(false);
@@ -129,7 +133,7 @@ public class settlementController : MonoBehaviour
private void Start()
{
// 确保 LowPass 在开始时处于原始位置(通常是 22000Hz,即不滤波)
// Documentation text normalized.
if (gameMusicMixer != null && !string.IsNullOrEmpty(lowpassParamName))
{
try { gameMusicMixer.SetFloat(lowpassParamName, 22000f); }
@@ -149,14 +153,14 @@ public class settlementController : MonoBehaviour
exit_toSelectSongs.onClick.RemoveListener(OnExitButtonClicked);
}
// 停止音乐过渡协程
// Documentation text normalized.
if (musicTransitionCoroutine != null)
{
StopCoroutine(musicTransitionCoroutine);
musicTransitionCoroutine = null;
}
// 停止 CanvasGroup 渐变协程
// Documentation text normalized.
if (canvasFadeCoroutine != null)
{
StopCoroutine(canvasFadeCoroutine);
@@ -175,10 +179,17 @@ public class settlementController : MonoBehaviour
public void startSettlement_uiUpdate()
{
// --- 确保结算界面开始时 CanvasGroup 为透明 ---
if (settlementUiInitialized)
{
Debug.Log("[SettlementController] startSettlement_uiUpdate ignored: settlement already initialized.");
return;
}
settlementUiInitialized = true;
// Documentation text normalized.
InitializeSettlementCanvas();
// --- 启用结算控制管理器 ---
// Documentation text normalized.
if (cdm != null)
{
cdm.SetActive(true);
@@ -191,7 +202,7 @@ public class settlementController : MonoBehaviour
if (gm != null) gm.RecordTotalPlayTime();
else { var activeGM = FindAnyObjectByType<GameManager>(); if (activeGM != null) activeGM.RecordTotalPlayTime(); }
// 准备结算音乐(在UI更新之前)
// Documentation text normalized.
PrepareSettlementMusic();
if(sm != null)
@@ -202,8 +213,8 @@ public class settlementController : MonoBehaviour
finalScore_Text.text = (sm.allSum_pmScore + sm.allSum_idolScore).ToString();
pmScoreSum_Text.text = sm.allSum_pmScore.ToString();
idolScoreSum_Text.text = sm.allSum_idolScore.ToString();
thisLevel_currentPercentage_Text.text = ((float)(sm.allSum_pmScore + sm.allSum_idolScore) / maxScore_sum * 100).ToString("F2") + "%";
thisLevel_progressBar_Image.fillAmount = (float)(sm.allSum_pmScore + sm.allSum_idolScore) / maxScore_sum;
thisLevel_currentPercentage_Text.text = ((float)(sm.allSum_pmScore + sm.allSum_idolScore) / _1000000 * 100).ToString("F2") + "%";
thisLevel_progressBar_Image.fillAmount = (float)(sm.allSum_pmScore + sm.allSum_idolScore) / _1000000;
int noteCountSum = sm.countPerfect + sm.countGreat + sm.countGood + sm.countMiss;
@@ -217,7 +228,7 @@ public class settlementController : MonoBehaviour
good_barFill_Image.fillAmount = (float)sm.countGood / noteCountSum;
miss_barFill_Image.fillAmount = (float)sm.countMiss / noteCountSum;
gameNote_rate.text = "已完成: " + noteCountSum.ToString() + "/" + bmm.parsedNoteAmount.ToString();
gameNote_rate.text = "宸插畬鎴? " + noteCountSum.ToString() + "/" + bmm.parsedNoteAmount.ToString();
perfectHitPercent_Text.text = ((float)sm.countPerfect / noteCountSum * 100).ToString("F1") + "%";
greatHitPercent_Text.text = ((float)sm.countGreat / noteCountSum * 100).ToString("F1") + "%";
@@ -295,19 +306,19 @@ public class settlementController : MonoBehaviour
int idol = sm != null ? sm.allSum_idolScore : 0;
int total = pm + idol;
// 更新最高分 (仅当本次总分更高时)
// Documentation text normalized.
thisSong_so.UpdateDifficultyRecord(diff, pm, idol);
// 更新上次游玩分数
// Documentation text normalized.
thisSong_so.UpdateChartScore(diff, total);
// 更新进度 (仅当进步时)
// Documentation text normalized.
if (thisSong_so.chartFiles != null)
{
var entry = thisSong_so.chartFiles.Find(e => e != null && e.difficulty == diff);
if (entry != null)
{
// 进度计算 (0..1)
// Documentation text normalized.
float newProgress = Mathf.Clamp01((float)total / (float)maxScore_sum);
if (newProgress > entry.levelProgressForThisDifficulty)
{
@@ -320,6 +331,9 @@ public class settlementController : MonoBehaviour
}
}
}
// --- 更新:保存到持久化存储(Build包必需) ---
thisSong_so.SavePersistent();
}
}
@@ -340,17 +354,17 @@ public class settlementController : MonoBehaviour
catch (System.Exception ex) { Debug.LogWarning("Failed to PopulateSettlementCards: " + ex); }
}
// 初始化结算完成,在界面UI显示后
// 尝试选择 MVP 英雄的大图
// Documentation text normalized.
// Documentation text normalized.
SetMvpHeroImageFromTopScorer();
StartMusicTransition();
// --- 修改:在所有逻辑末尾开始 CanvasGroup 渐变 ---
// Documentation text normalized.
StartCanvasFadeIn();
}
/// <summary>
/// 初始化结算界面的 CanvasGroup 为透明状态
/// Documentation text normalized.
/// </summary>
private void InitializeSettlementCanvas()
{
@@ -367,16 +381,14 @@ public class settlementController : MonoBehaviour
}
}
// 缓存 AllyHero_SO 数组,避免在结算界面多次调用昂贵的 Resources.LoadAll
// Documentation text normalized.
private static AllyHero_SO[] _cachedAllyHeroSOs;
/// <summary>
/// 从所有dlcData中查找并准备当前歌曲所属DLC的结算音乐
/// Documentation text normalized.
/// </summary>
private void PrepareSettlementMusic()
{
// --- 修改:移除 CanvasGroup 相关设置,已移动到结算逻辑末尾调用 ---
if (thisSong_so == null)
{
Debug.LogWarning("[SettlementController] thisSong_so is null, cannot prepare settlement music");
@@ -389,58 +401,48 @@ public class settlementController : MonoBehaviour
return;
}
// 使用异步或分帧逻辑来查找 DLC
StartCoroutine(PrepareSettlementMusicRoutine());
}
private IEnumerator PrepareSettlementMusicRoutine()
{
// 加载 dlcData ScriptableObjects
dlcData[] allDlcs = Resources.LoadAll<dlcData>("");
dlcData foundDlc = null;
// 遍历所有DLC数据以找到包含当前歌曲的DLC
for (int i = 0; i < allDlcs.Length; i++)
{
var dlc = allDlcs[i];
dlcData dlc = allDlcs[i];
if (dlc == null || dlc.songList == null) continue;
if (dlc.songList.Contains(thisSong_so))
{
foundDlc = dlc;
break;
}
// 每处理 20 个 DLC 等待一帧
if (i > 0 && i % 20 == 0) yield return null;
if (!dlc.songList.Contains(thisSong_so)) continue;
foundDlc = dlc;
break;
}
if (foundDlc == null)
{
Debug.LogWarning($"[SettlementController] No DLC found containing song '{thisSong_so.songName}'");
yield break;
return;
}
if (foundDlc.settlementMusic == null)
{
Debug.LogWarning($"[SettlementController] DLC '{foundDlc.dlcName}' does not have settlement music assigned");
yield break;
return;
}
bool clipChanged = settlementAudioSource.clip != foundDlc.settlementMusic;
if (clipChanged)
{
settlementAudioSource.Stop();
settlementAudioSource.clip = foundDlc.settlementMusic;
settlementAudioSource.time = 0f;
}
// 设置结算音乐的AudioSource
settlementAudioSource.clip = foundDlc.settlementMusic;
settlementAudioSource.loop = true;
settlementAudioSource.playOnAwake = false;
// 初始音量并静音等待播放
settlementAudioSource.volume = 1f;
settlementAudioSource.mute = true;
settlementAudioSource.Stop();
settlementAudioSource.mute = false;
Debug.Log($"[SettlementController] Prepared settlement music from DLC '{foundDlc.dlcName}': {foundDlc.settlementMusic.name}");
}
/// <summary>
/// 开始音乐过渡,将原游戏背景音乐淡出,然后播放结算音乐
/// Documentation text normalized.
/// </summary>
private void StartMusicTransition()
{
@@ -452,69 +454,79 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// 音乐过渡协程:
/// 1. 将游戏音乐的低通滤波器从 22000Hz 逐渐降至 0Hz,同时音量降至 0
/// 2. 渐变完成后停止原音轨并开始播放结算音乐
/// Documentation text normalized.
/// Documentation text normalized.
/// Documentation text normalized.
/// </summary>
private IEnumerator MusicTransitionRoutine()
{
float elapsed = 0f;
float startLowpass = 22000f;
float endLowpass = 0f;
float transitionDuration = Mathf.Max(0.01f, lowpassFadeDuration);
// --- 获取当前音量作为起始点 ---
float startVolume = (oriGameMusicSource != null) ? oriGameMusicSource.volume : 1f;
bool settlementMusicStarted = false;
float settlementStartVolume = 0f;
// 如果原游戏音轨和混音器参数存在,执行低通滤波和音量淡出
if (oriGameMusicSource != null && gameMusicMixer != null && !string.IsNullOrEmpty(lowpassParamName))
{
Debug.Log($"[SettlementController] Starting lowpass and volume fade over {lowpassFadeDuration}s");
while (elapsed < lowpassFadeDuration)
{
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / Mathf.Max(0.0001f, lowpassFadeDuration));
// 1. 设置低通滤波器
float currentLowpass = Mathf.Lerp(startLowpass, endLowpass, t);
try { gameMusicMixer.SetFloat(lowpassParamName, currentLowpass); }
catch (System.Exception ex) { Debug.LogWarning($"Mixer error: {ex.Message}"); }
// 2. --- 修改:平滑降低音量 ---
oriGameMusicSource.volume = Mathf.Lerp(startVolume, 0f, t);
yield return null;
}
// 确保最终状态
try { gameMusicMixer.SetFloat(lowpassParamName, endLowpass); } catch { }
// --- 修改:音量归零并暂停/停止 ---
oriGameMusicSource.volume = 0f;
oriGameMusicSource.Pause(); // 也可以使用 .Stop()
Debug.Log("[SettlementController] Lowpass and volume fade complete, game music paused.");
}
else
{
Debug.LogWarning("[SettlementController] oriGameMusicSource or gameMusicMixer not assigned, skipping fade");
}
// 过渡完成后,开始播放结算音乐
// Start settlement music immediately to avoid delayed playback at settlement start.
if (settlementAudioSource != null && settlementAudioSource.clip != null)
{
try
{
settlementAudioSource.mute = false;
if (!settlementAudioSource.isPlaying)
{
settlementAudioSource.volume = 0f;
settlementAudioSource.Play();
settlementStartVolume = 0f;
}
else
{
settlementStartVolume = Mathf.Clamp01(settlementAudioSource.volume);
}
settlementMusicStarted = true;
Debug.Log($"[SettlementController] Settlement music active: {settlementAudioSource.clip.name}");
}
catch (System.Exception ex)
{
Debug.LogWarning($"[SettlementController] Failed to start settlement music immediately: {ex.Message}");
}
}
if (oriGameMusicSource != null)
{
Debug.Log($"[SettlementController] Starting game-music fade out over {transitionDuration}s");
while (elapsed < transitionDuration)
{
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / transitionDuration);
oriGameMusicSource.volume = Mathf.Lerp(startVolume, 0f, t);
if (settlementMusicStarted && settlementAudioSource != null)
settlementAudioSource.volume = Mathf.Lerp(settlementStartVolume, 1f, t);
yield return null;
}
oriGameMusicSource.volume = 0f;
oriGameMusicSource.Pause();
Debug.Log("[SettlementController] Game music fade complete, game music paused.");
}
else
{
Debug.LogWarning("[SettlementController] oriGameMusicSource not assigned, skipping game music fade");
if (settlementMusicStarted && settlementAudioSource != null)
settlementAudioSource.volume = 1f;
}
if (!settlementMusicStarted && settlementAudioSource != null && settlementAudioSource.clip != null)
{
try
{
settlementAudioSource.mute = false;
settlementAudioSource.volume = 1f;
settlementAudioSource.Play();
Debug.Log($"[SettlementController] Settlement music started: {settlementAudioSource.clip.name}");
// --- 一旦结算音乐开始播放,立刻将 LowPass 设置回原位确保音频正常 ---
if (gameMusicMixer != null && !string.IsNullOrEmpty(lowpassParamName))
{
gameMusicMixer.SetFloat(lowpassParamName, 22000f);
Debug.Log("[SettlementController] Reset lowpass to 22000Hz for normal audio quality.");
}
}
catch (System.Exception ex)
{
@@ -526,7 +538,7 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// 开始 CanvasGroup 渐入效果
/// Documentation text normalized.
/// </summary>
private void StartCanvasFadeIn()
{
@@ -538,7 +550,7 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// CanvasGroup 渐入协程:0.25秒内从 alpha=0 渐变到 alpha=1
/// Documentation text normalized.
/// </summary>
private IEnumerator CanvasFadeInRoutine()
{
@@ -563,7 +575,7 @@ public class settlementController : MonoBehaviour
yield return null;
}
// ȷ״̬
// Documentation text normalized.
settlementCanvasGroup.alpha = targetAlpha;
settlementCanvasGroup.interactable = true;
settlementCanvasGroup.blocksRaycasts = true;
@@ -574,13 +586,13 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// 重新开始当前游戏 - 重新加载场景并重置游戏状态
/// Documentation text normalized.
/// </summary>
private void OnReplayButtonClicked()
{
Debug.Log("[SettlementController] Replay button clicked - restarting current game");
// 验证必要引用
// Documentation text normalized.
if (bmm == null)
{
Debug.LogError("[SettlementController] BeatmapManager is null, cannot replay");
@@ -593,7 +605,7 @@ public class settlementController : MonoBehaviour
return;
}
// 保存当前关卡信息用于重新加载
// Documentation text normalized.
SongData songToReplay = bmm.assignedSongData;
int difficultyToReplay = bmm.assignedDifficulty;
@@ -605,16 +617,16 @@ public class settlementController : MonoBehaviour
Debug.Log($"[SettlementController] Reloading song: {songToReplay.songName}, difficulty: {difficultyToReplay}");
// 停止结算音乐
// Documentation text normalized.
if (settlementAudioSource != null && settlementAudioSource.isPlaying)
{
settlementAudioSource.Stop();
}
// 设置 BeatmapManager 为下一次加载准备
// Documentation text normalized.
BeatmapManager.SetPendingSong(songToReplay, difficultyToReplay);
// 重新加载当前场景
// Documentation text normalized.
StartCoroutine(LoadSceneAsync(SceneManager.GetActiveScene().name));
}
@@ -628,19 +640,19 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// 返回选曲界面
/// Documentation text normalized.
/// </summary>
private void OnExitButtonClicked()
{
Debug.Log("[SettlementController] Exit button clicked - returning to song selection");
// 停止结算音乐
// Documentation text normalized.
if (settlementAudioSource != null && settlementAudioSource.isPlaying)
{
settlementAudioSource.Stop();
}
// 清除任何待处理的歌曲信息
// Documentation text normalized.
BeatmapManager.pendingSongData = null;
BeatmapManager.pendingDifficulty = -1;
@@ -702,8 +714,8 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// 根据各角色(按槽位选出最高分的角色),设置 AllyHero_SO 中的 ally_hero_HD_image 赋值给 mvp_hero_hd_image
/// 这里使用 ScoreManager 的 per-track pm sums,如果没有则从场景中的 AllyCombatant.currentScore 读取
/// Documentation text normalized.
/// Documentation text normalized.
/// </summary>
private void SetMvpHeroImageFromTopScorer()
{
@@ -814,3 +826,4 @@ public class settlementController : MonoBehaviour
}
}
}