技能主要更新,修复卡顿并加入动画,以及各种其他更新。

This commit is contained in:
FloatGaming
2026-02-07 21:05:17 +08:00
parent abeca51be5
commit 1ac3cd0104
1349 changed files with 1526749 additions and 24850 deletions
@@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.Serialization;
@@ -9,22 +9,22 @@ using UnityEditor;
public class settlementController : MonoBehaviour
{
[Header("֮")]
[Header("管理器与基础引用")]
[SerializeField] private BeatmapManager bmm;
[SerializeField] private ScoreManager sm;
public GameManager gm;
private SongData thisSong_so;
private int maxScore_sum = 2000000;
[SerializeField] private Image thisSong_backPic;
[Header("ת֮ť")]
[Header("跳转控制按钮")]
public Button exit_toSelectSongs;
public Button replay_thisGame;
public Button display_rankList;
public Button share_toSocialMedia;
[Header("ıͽ")]
[Header("文本与进度显示")]
public Text songName_Text;
[Tooltip("ǰؿĽȰٷֱ")]
[Tooltip("当前关卡的进度百分比")]
public Text thisLevel_currentPercentage_Text;
public Text finalScore_Text;
public Text pmScoreSum_Text;
@@ -33,26 +33,26 @@ public class settlementController : MonoBehaviour
public Image thisLevel_progressBar_Image;
[Header("׼ȷ")]
[Header("准确度权重算法")]
public float perfect_weight = 1f;
public float great_weight = 0.6666667f;
public float good_weight = 0.333333f;
public float miss_weight = 0;
[Header("Ϣ")]
[Header("结算奖励信息")]
public Text reward_playerEXP_Text;
public Text reward_money_Text;
public Text reward_idolEXP_bottle_Text;
[Header("Ŷӽ")]
[Header("队伍展示")]
public loadSettlementTeamPrefab settlementTeamLoader;
public Image mvp_hero_hd_image;
[Header("Ǯ")]
[Header("结算获得金钱")]
[SerializeField] private long moneyToGive_thisLevel;
// õͳ
[Header("ͳ")]
// 得到评分统计
[Header("音符判定统计")]
public Text perfectHitCount_Text;
public Text perfectHitPercent_Text;
public Image perfect_barFill_Image;
@@ -76,27 +76,27 @@ public class settlementController : MonoBehaviour
public Text lateHitCount_Text;
public Text avgOffset_Text;
[Header("ϵͳ")]
[Tooltip("ֲ½")]
[Header("结算音频控制")]
[Tooltip("结算界面背景音乐,播放结算流程")]
public AudioSource settlementAudioSource;
[Tooltip("ϷֲԭϷ֣")]
[Tooltip("游戏背景音乐(通常是原游戏曲目)")]
public AudioSource oriGameMusicSource;
[Tooltip("Ƶڵͨ˲")]
[Tooltip("音频混音器,用于低通滤波等效果")]
public AudioMixer gameMusicMixer;
[Tooltip("Ƶеͨ˲")]
[Tooltip("音频混音器中的低通滤波参数名")]
public string lowpassParamName = "inGameMusic_lowpass";
[Tooltip("ͨ˲ʱ")]
[Tooltip("低通滤波器渐变持续时间(秒)")]
public float lowpassFadeDuration = 2f;
[Tooltip(" CanvasGroupڵЧ")]
[Tooltip("结算界面 CanvasGroup,用于淡入效果")]
public CanvasGroup settlementCanvasGroup;
[Header("")]
[Tooltip("")]
[Header("结算控制组件")]
[Tooltip("结算控制管理器")]
public GameObject cdm;
private Coroutine musicTransitionCoroutine;
@@ -104,7 +104,7 @@ public class settlementController : MonoBehaviour
private void Awake()
{
// Setup button listeners
// 设置按钮监听
if (replay_thisGame != null)
{
replay_thisGame.onClick.AddListener(OnReplayButtonClicked);
@@ -115,11 +115,11 @@ public class settlementController : MonoBehaviour
exit_toSelectSongs.onClick.AddListener(OnExitButtonClicked);
}
// CDM ڿʼʱֽ״̬
// 确保 CDM 对象在开始时处于关闭状态
if (cdm != null)
{
cdm.SetActive(false);
if (GameConfig.verboseLogs) Debug.Log("[SettlementController] CDM object disabled at startup");
if (JudgeManager.IsDebugEnabled) Debug.Log("[SettlementController] CDM object disabled at startup");
}
else
{
@@ -149,14 +149,14 @@ public class settlementController : MonoBehaviour
exit_toSelectSongs.onClick.RemoveListener(OnExitButtonClicked);
}
// ֹֹͣЭ
// 停止音乐过渡协程
if (musicTransitionCoroutine != null)
{
StopCoroutine(musicTransitionCoroutine);
musicTransitionCoroutine = null;
}
// ֹͣ CanvasGroup Э
// 停止 CanvasGroup 渐变协程
if (canvasFadeCoroutine != null)
{
StopCoroutine(canvasFadeCoroutine);
@@ -175,10 +175,10 @@ public class settlementController : MonoBehaviour
public void startSettlement_uiUpdate()
{
// --- ڽ̿ʼʱ CanvasGroup Ϊ͸ ---
// --- 确保结算界面开始时 CanvasGroup 为透明 ---
InitializeSettlementCanvas();
// --- ý ---
// --- 启用结算控制管理器 ---
if (cdm != null)
{
cdm.SetActive(true);
@@ -189,9 +189,9 @@ public class settlementController : MonoBehaviour
// --- Statistics: Record total play time at settlement ---
if (gm != null) gm.RecordTotalPlayTime();
else { var activeGM = FindObjectOfType<GameManager>(); if (activeGM != null) activeGM.RecordTotalPlayTime(); }
else { var activeGM = FindAnyObjectByType<GameManager>(); if (activeGM != null) activeGM.RecordTotalPlayTime(); }
// ׼֣UI֮ǰ
// 准备结算音乐(在UI更新之前)
PrepareSettlementMusic();
if(sm != null)
@@ -277,6 +277,7 @@ public class settlementController : MonoBehaviour
InGamePerformanceManager.Instance.UpdateTotalCure(totalCure);
InGamePerformanceManager.Instance.UpdateTotalDamage(totalDamage);
InGamePerformanceManager.Instance.UpdateTotalManaRestored(totalMana);
if (sm != null) InGamePerformanceManager.Instance.UpdateTotalScore(sm.allSum_pmScore + sm.allSum_idolScore);
// Load and display achievement prefabs
InGamePerformanceManager.Instance.LoadArchievePrefab();
@@ -326,7 +327,7 @@ public class settlementController : MonoBehaviour
if (settlementTeamLoader == null)
{
// try to auto-locate loader in scene if not assigned in inspector
settlementTeamLoader = FindObjectOfType<loadSettlementTeamPrefab>();
settlementTeamLoader = FindAnyObjectByType<loadSettlementTeamPrefab>();
}
if (settlementTeamLoader != null)
@@ -334,22 +335,22 @@ public class settlementController : MonoBehaviour
// ensure loader has key references
if (settlementTeamLoader.sm == null) settlementTeamLoader.sm = sm ?? ScoreManager.Instance;
if (settlementTeamLoader.tuic == null) settlementTeamLoader.tuic = teamUIController.Instance;
if (settlementTeamLoader.gm == null) settlementTeamLoader.gm = gm ?? FindObjectOfType<GameManager>();
if (settlementTeamLoader.gm == null) settlementTeamLoader.gm = gm ?? FindAnyObjectByType<GameManager>();
try { settlementTeamLoader.PopulateSettlementCards(); }
catch (System.Exception ex) { Debug.LogWarning("Failed to PopulateSettlementCards: " + ex); }
}
// ʼֹɣڽUIʾ
// ѡ MVP ͼƬ
// 初始化结算完成,在界面UI显示后
// 尝试选择 MVP 英雄的大图
SetMvpHeroImageFromTopScorer();
StartMusicTransition();
// --- ޸ģ߼ĩβʼ CanvasGroup ---
// --- 修改:在所有逻辑末尾开始 CanvasGroup 渐变 ---
StartCanvasFadeIn();
}
/// <summary>
/// ʼ CanvasGroup Ϊ͸״̬
/// 初始化结算界面的 CanvasGroup 为透明状态
/// </summary>
private void InitializeSettlementCanvas()
{
@@ -366,12 +367,15 @@ public class settlementController : MonoBehaviour
}
}
// 缓存 AllyHero_SO 数组,避免在结算界面多次调用昂贵的 Resources.LoadAll
private static AllyHero_SO[] _cachedAllyHeroSOs;
/// <summary>
/// dlcDataзҰǰDLC׼
/// 从所有dlcData中查找并准备当前歌曲所属DLC的结算音乐
/// </summary>
private void PrepareSettlementMusic()
{
// --- ޸ģƳ CanvasGroup ãڽ߼ĩβŵ ---
// --- 修改:移除 CanvasGroup 相关设置,已移动到结算逻辑末尾调用 ---
if (thisSong_so == null)
{
@@ -385,13 +389,20 @@ public class settlementController : MonoBehaviour
return;
}
// dlcData ScriptableObjects
// 使用异步或分帧逻辑来查找 DLC
StartCoroutine(PrepareSettlementMusicRoutine());
}
private IEnumerator PrepareSettlementMusicRoutine()
{
// 加载 dlcData ScriptableObjects
dlcData[] allDlcs = Resources.LoadAll<dlcData>("");
dlcData foundDlc = null;
// DLCҰǰDLC
foreach (var dlc in allDlcs)
// 遍历所有DLC数据以找到包含当前歌曲的DLC
for (int i = 0; i < allDlcs.Length; i++)
{
var dlc = allDlcs[i];
if (dlc == null || dlc.songList == null) continue;
if (dlc.songList.Contains(thisSong_so))
@@ -399,37 +410,37 @@ public class settlementController : MonoBehaviour
foundDlc = dlc;
break;
}
// 每处理 20 个 DLC 等待一帧
if (i > 0 && i % 20 == 0) yield return null;
}
if (foundDlc == null)
{
Debug.LogWarning($"[SettlementController] No DLC found containing song '{thisSong_so.songName}'");
return;
yield break;
}
if (foundDlc.settlementMusic == null)
{
Debug.LogWarning($"[SettlementController] DLC '{foundDlc.dlcName}' does not have settlement music assigned");
return;
yield break;
}
// ýֵAudioSource
// 设置结算音乐的AudioSource
settlementAudioSource.clip = foundDlc.settlementMusic;
settlementAudioSource.loop = true;
settlementAudioSource.playOnAwake = false;
// ͣȴ
// 初始音量并静音等待播放
settlementAudioSource.volume = 1f;
settlementAudioSource.mute = true;
settlementAudioSource.Stop();
Debug.Log($"[SettlementController] Prepared settlement music from DLC '{foundDlc.dlcName}': {foundDlc.settlementMusic.name}");
// --- ޸ģƳ CanvasGroup ãڽ߼ĩβŵ ---
}
/// <summary>
/// ʼֹɣϷ֣ͨͨ˲Ȼ󲥷Ž
/// 开始音乐过渡,将原游戏背景音乐淡出,然后播放结算音乐
/// </summary>
private void StartMusicTransition()
{
@@ -441,9 +452,9 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// ֹЭ̣
/// 1. Ϸֵĵͨ˲22000Hz𽥽0Hzͬʱ0
/// 2. ֹͣԭֲʼŽ
/// 音乐过渡协程:
/// 1. 将游戏音乐的低通滤波器从 22000Hz 逐渐降至 0Hz,同时音量降至 0
/// 2. 渐变完成后停止原音轨并开始播放结算音乐
/// </summary>
private IEnumerator MusicTransitionRoutine()
{
@@ -451,10 +462,10 @@ public class settlementController : MonoBehaviour
float startLowpass = 22000f;
float endLowpass = 0f;
// --- ¼ʼ ---
// --- 获取当前音量作为起始点 ---
float startVolume = (oriGameMusicSource != null) ? oriGameMusicSource.volume : 1f;
// ԭϷԴͻڣеͨ˲
// 如果原游戏音轨和混音器参数存在,执行低通滤波和音量淡出
if (oriGameMusicSource != null && gameMusicMixer != null && !string.IsNullOrEmpty(lowpassParamName))
{
Debug.Log($"[SettlementController] Starting lowpass and volume fade over {lowpassFadeDuration}s");
@@ -464,23 +475,23 @@ public class settlementController : MonoBehaviour
elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(elapsed / Mathf.Max(0.0001f, lowpassFadeDuration));
// 1. õͨ˲
// 1. 设置低通滤波器
float currentLowpass = Mathf.Lerp(startLowpass, endLowpass, t);
try { gameMusicMixer.SetFloat(lowpassParamName, currentLowpass); }
catch (System.Exception ex) { Debug.LogWarning($"Mixer error: {ex.Message}"); }
// 2. --- ޸ģƽ ---
// 2. --- 修改:平滑降低音量 ---
oriGameMusicSource.volume = Mathf.Lerp(startVolume, 0f, t);
yield return null;
}
// ȷ״̬
// 确保最终状态
try { gameMusicMixer.SetFloat(lowpassParamName, endLowpass); } catch { }
// --- ޸ģͣ/ֹͣ ---
// --- 修改:音量归零并暂停/停止 ---
oriGameMusicSource.volume = 0f;
oriGameMusicSource.Pause(); // ʹ .Stop()
oriGameMusicSource.Pause(); // 也可以使用 .Stop()
Debug.Log("[SettlementController] Lowpass and volume fade complete, game music paused.");
}
@@ -489,7 +500,7 @@ public class settlementController : MonoBehaviour
Debug.LogWarning("[SettlementController] oriGameMusicSource or gameMusicMixer not assigned, skipping fade");
}
// ɺ󣬿ʼŽ
// 过渡完成后,开始播放结算音乐
if (settlementAudioSource != null && settlementAudioSource.clip != null)
{
try
@@ -515,7 +526,7 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// ʼ CanvasGroup Ч
/// 开始 CanvasGroup 渐入效果
/// </summary>
private void StartCanvasFadeIn()
{
@@ -527,7 +538,7 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// CanvasGroup Э̣0.25ڴ alpha=0 alpha=1
/// CanvasGroup 渐入协程:0.25秒内从 alpha=0 渐变到 alpha=1
/// </summary>
private IEnumerator CanvasFadeInRoutine()
{
@@ -563,13 +574,13 @@ public class settlementController : MonoBehaviour
}
/// <summary>
/// ǰϷ - ¼ֺͳʼϷ״̬
/// 重新开始当前游戏 - 重新加载场景并重置游戏状态
/// </summary>
private void OnReplayButtonClicked()
{
Debug.Log("[SettlementController] Replay button clicked - restarting current game");
// ֤Ҫ
// 验证必要引用
if (bmm == null)
{
Debug.LogError("[SettlementController] BeatmapManager is null, cannot replay");
@@ -582,7 +593,7 @@ public class settlementController : MonoBehaviour
return;
}
// 浱ǰؿϢ¼أ
// 保存当前关卡信息用于重新加载
SongData songToReplay = bmm.assignedSongData;
int difficultyToReplay = bmm.assignedDifficulty;
@@ -594,33 +605,42 @@ public class settlementController : MonoBehaviour
Debug.Log($"[SettlementController] Reloading song: {songToReplay.songName}, difficulty: {difficultyToReplay}");
// ֹͣ
// 停止结算音乐
if (settlementAudioSource != null && settlementAudioSource.isPlaying)
{
settlementAudioSource.Stop();
}
// BeatmapManager Ϊһ׼
// 设置 BeatmapManager 为下一次加载准备
BeatmapManager.SetPendingSong(songToReplay, difficultyToReplay);
// ¼صǰGamePlay_gamePlay
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
// 重新加载当前场景
StartCoroutine(LoadSceneAsync(SceneManager.GetActiveScene().name));
}
private IEnumerator LoadSceneAsync(string sceneName)
{
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
while (!asyncLoad.isDone)
{
yield return null;
}
}
/// <summary>
/// ѡ
/// 返回选曲界面
/// </summary>
private void OnExitButtonClicked()
{
Debug.Log("[SettlementController] Exit button clicked - returning to song selection");
// ֹͣ
// 停止结算音乐
if (settlementAudioSource != null && settlementAudioSource.isPlaying)
{
settlementAudioSource.Stop();
}
// κδ
// 清除任何待处理的歌曲信息
BeatmapManager.pendingSongData = null;
BeatmapManager.pendingDifficulty = -1;
@@ -634,7 +654,7 @@ public class settlementController : MonoBehaviour
}
else
{
SceneManager.LoadScene("selectYourSongFirst");
StartCoroutine(LoadSceneAsync("selectYourSongFirst"));
}
}
@@ -643,7 +663,8 @@ public class settlementController : MonoBehaviour
{
if (gm == null || gm.blackMaskImage == null)
{
SceneManager.LoadScene(sceneName);
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
while (!asyncLoad.isDone) yield return null;
yield break;
}
@@ -673,12 +694,16 @@ public class settlementController : MonoBehaviour
blackMask.color = fc;
// load target scene
SceneManager.LoadScene(sceneName);
AsyncOperation asyncOp = SceneManager.LoadSceneAsync(sceneName);
while (!asyncOp.isDone)
{
yield return null;
}
}
/// <summary>
/// ݸɫѡ߷ֵĽɫ AllyHero_SO е ally_hero_HD_image ֵ mvp_hero_hd_image
/// ʹ ScoreManager per-track pm sums˵ AllyCombatant.currentScore
/// 根据各角色(按槽位选出最高分的角色),设置 AllyHero_SO 中的 ally_hero_HD_image 赋值给 mvp_hero_hd_image
/// 这里使用 ScoreManager per-track pm sums,如果没有则从场景中的 AllyCombatant.currentScore 读取
/// </summary>
private void SetMvpHeroImageFromTopScorer()
{
@@ -750,8 +775,11 @@ public class settlementController : MonoBehaviour
allyId = teamUIController.Instance.allySlotIds[topIndex];
if (allyId > 0)
{
var arr = Resources.LoadAll<AllyHero_SO>("");
foreach (var a in arr)
if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0)
{
_cachedAllyHeroSOs = Resources.LoadAll<AllyHero_SO>("");
}
foreach (var a in _cachedAllyHeroSOs)
{
if (a != null && a.ally_heroID == allyId) { heroSO = a; break; }
}
@@ -761,11 +789,14 @@ public class settlementController : MonoBehaviour
// final fallback: try direct Resources lookup by scanning all and picking first non-null for slot
if (heroSO == null)
{
var arr = Resources.LoadAll<AllyHero_SO>("");
if (arr != null && arr.Length > 0)
if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0)
{
_cachedAllyHeroSOs = Resources.LoadAll<AllyHero_SO>("");
}
if (_cachedAllyHeroSOs != null && _cachedAllyHeroSOs.Length > 0)
{
// attempt to match by name or just pick first
heroSO = arr[0] as AllyHero_SO;
heroSO = _cachedAllyHeroSOs[0] as AllyHero_SO;
}
}