using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using UnityEngine.Serialization; using UnityEngine.SceneManagement; using System.Collections; using UnityEngine.Audio; using UnityEditor; public class settlementController : MonoBehaviour { [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("跳转控制按钮")] public Button exit_toSelectSongs; public Button replay_thisGame; public Button display_rankList; public Button share_toSocialMedia; [Header("文本与进度显示")] public Text songName_Text; [Tooltip("当前关卡的进度百分比")] public Text thisLevel_currentPercentage_Text; public Text finalScore_Text; public Text pmScoreSum_Text; public Text idolScoreSum_Text; public Text accuracy_Text; public Image thisLevel_progressBar_Image; [Header("准确度权重算法")] public float perfect_weight = 1f; public float great_weight = 0.6666667f; public float good_weight = 0.333333f; public float miss_weight = 0; [Header("结算奖励信息")] public Text reward_playerEXP_Text; public Text reward_money_Text; public Text reward_idolEXP_bottle_Text; [Header("队伍展示")] public loadSettlementTeamPrefab settlementTeamLoader; public Image mvp_hero_hd_image; [Header("结算获得金钱")] [SerializeField] private long moneyToGive_thisLevel; // 得到评分统计 [Header("音符判定统计")] public Text perfectHitCount_Text; public Text perfectHitPercent_Text; public Image perfect_barFill_Image; public Text greatHitCount_Text; public Text greatHitPercent_Text; public Image great_barFill_Image; public Text goodHitCount_Text; public Text goodHitPercent_Text; public Image good_barFill_Image; public Text missHitCount_Text; public Text missHitPercent_Text; public Image miss_barFill_Image; public Text gameNote_rate; [Header("Timing Statistics")] public Text earlyHitCount_Text; public Text lateHitCount_Text; public Text avgOffset_Text; [Header("结算音频控制")] [Tooltip("结算界面背景音乐,播放结算流程")] public AudioSource settlementAudioSource; [Tooltip("游戏背景音乐(通常是原游戏曲目)")] public AudioSource oriGameMusicSource; [Tooltip("音频混音器,用于低通滤波等效果")] public AudioMixer gameMusicMixer; [Tooltip("音频混音器中的低通滤波参数名")] public string lowpassParamName = "inGameMusic_lowpass"; [Tooltip("低通滤波器渐变持续时间(秒)")] public float lowpassFadeDuration = 2f; [Tooltip("结算界面 CanvasGroup,用于淡入效果")] public CanvasGroup settlementCanvasGroup; [Header("结算控制组件")] [Tooltip("结算控制管理器")] public GameObject cdm; private Coroutine musicTransitionCoroutine; private Coroutine canvasFadeCoroutine; private void Awake() { // 设置按钮监听 if (replay_thisGame != null) { replay_thisGame.onClick.AddListener(OnReplayButtonClicked); } if (exit_toSelectSongs != null) { exit_toSelectSongs.onClick.AddListener(OnExitButtonClicked); } // 确保 CDM 对象在开始时处于关闭状态 if (cdm != null) { cdm.SetActive(false); if (JudgeManager.IsDebugEnabled) Debug.Log("[SettlementController] CDM object disabled at startup"); } else { Debug.LogWarning("[SettlementController] CDM object is not assigned"); } } private void Start() { // 确保 LowPass 在开始时处于原始位置(通常是 22000Hz,即不滤波) if (gameMusicMixer != null && !string.IsNullOrEmpty(lowpassParamName)) { try { gameMusicMixer.SetFloat(lowpassParamName, 22000f); } catch { } } } private void OnDestroy() { if (replay_thisGame != null) { replay_thisGame.onClick.RemoveListener(OnReplayButtonClicked); } if (exit_toSelectSongs != null) { exit_toSelectSongs.onClick.RemoveListener(OnExitButtonClicked); } // 停止音乐过渡协程 if (musicTransitionCoroutine != null) { StopCoroutine(musicTransitionCoroutine); musicTransitionCoroutine = null; } // 停止 CanvasGroup 渐变协程 if (canvasFadeCoroutine != null) { StopCoroutine(canvasFadeCoroutine); canvasFadeCoroutine = null; } } // Start is called once before the first execution of Update after the MonoBehaviour is created public void getThisSong_info() { if (bmm != null) { thisSong_so = bmm.assignedSongData; } } public void startSettlement_uiUpdate() { // --- 确保结算界面开始时 CanvasGroup 为透明 --- InitializeSettlementCanvas(); // --- 启用结算控制管理器 --- if (cdm != null) { cdm.SetActive(true); Debug.Log("[SettlementController] CDM object enabled at settlement start"); } getThisSong_info(); // --- Statistics: Record total play time at settlement --- if (gm != null) gm.RecordTotalPlayTime(); else { var activeGM = FindAnyObjectByType(); if (activeGM != null) activeGM.RecordTotalPlayTime(); } // 准备结算音乐(在UI更新之前) PrepareSettlementMusic(); if(sm != null) { songName_Text.text = bmm.parsedTitle; thisSong_backPic.sprite = bmm.assignedSongData.fullscreen_songPicture; 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; int noteCountSum = sm.countPerfect + sm.countGreat + sm.countGood + sm.countMiss; perfectHitCount_Text.text = sm.countPerfect.ToString(); greatHitCount_Text.text = sm.countGreat.ToString(); goodHitCount_Text.text = sm.countGood.ToString(); missHitCount_Text.text = sm.countMiss.ToString(); perfect_barFill_Image.fillAmount = (float)sm.countPerfect / noteCountSum; great_barFill_Image.fillAmount = (float)sm.countGreat / noteCountSum; good_barFill_Image.fillAmount = (float)sm.countGood / noteCountSum; miss_barFill_Image.fillAmount = (float)sm.countMiss / noteCountSum; 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") + "%"; goodHitPercent_Text.text = ((float)sm.countGood / noteCountSum * 100).ToString("F1") + "%"; missHitPercent_Text.text = ((float)sm.countMiss / noteCountSum * 100).ToString("F1") + "%"; accuracy_Text.text = ((float)(sm.countPerfect * perfect_weight + sm.countGreat * great_weight + sm.countGood * good_weight + sm.countMiss * miss_weight) / noteCountSum * 100).ToString("F3") + "%"; // Timing Statistics if (earlyHitCount_Text != null) earlyHitCount_Text.text = sm.countEarly.ToString(); if (lateHitCount_Text != null) lateHitCount_Text.text = sm.countLate.ToString(); if (avgOffset_Text != null) { float avg = sm.offsetCount > 0 ? sm.totalOffsetMs / sm.offsetCount : 0f; avgOffset_Text.text = avg.ToString("F2") + " ms"; } } else Debug.LogError("score manager is null"); // --- Achievement System: Load and display achievements --- if (InGamePerformanceManager.Instance != null) { // Calculate total cure, damage and mana from teamUIController float totalCure = 0; float totalDamage = 0; float totalMana = 0; if (teamUIController.Instance != null) { if (teamUIController.Instance.totalHealProvided != null) { foreach (float heal in teamUIController.Instance.totalHealProvided) { totalCure += heal; } } if (teamUIController.Instance.totalDamageDealt != null) { foreach (float dmg in teamUIController.Instance.totalDamageDealt) { totalDamage += dmg; } } if (teamUIController.Instance.totalManaRestored != null) { foreach (float mana in teamUIController.Instance.totalManaRestored) { totalMana += mana; } } Debug.Log($"[SettlementController] Stats Aggregated - Cure: {totalCure}, Damage: {totalDamage}, Mana: {totalMana}"); } // Update achievement categories 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(); } // Persist run results into the SongData SO for this difficulty // (update personal / idol / total records and per-entry progress if improved) getThisSong_info(); // ensure thisSong_so set if (thisSong_so != null && bmm != null) { int diff = bmm.assignedDifficulty; if (diff >= 0) { int pm = sm != null ? sm.allSum_pmScore : 0; int idol = sm != null ? sm.allSum_idolScore : 0; int total = pm + idol; // 更新最高分 (仅当本次总分更高时) thisSong_so.UpdateDifficultyRecord(diff, pm, idol); // 更新上次游玩分数 thisSong_so.UpdateChartScore(diff, total); // 更新进度 (仅当进步时) if (thisSong_so.chartFiles != null) { var entry = thisSong_so.chartFiles.Find(e => e != null && e.difficulty == diff); if (entry != null) { // 进度计算 (0..1) float newProgress = Mathf.Clamp01((float)total / (float)maxScore_sum); if (newProgress > entry.levelProgressForThisDifficulty) { entry.levelProgressForThisDifficulty = newProgress; } if (thisSong_so.thisLevel_selectedDifficultyID == diff) { thisSong_so.current_levelProgress = Mathf.Max(thisSong_so.current_levelProgress, entry.levelProgressForThisDifficulty); } } } } } // Populate settlement team cards if a loader is assigned if (settlementTeamLoader == null) { // try to auto-locate loader in scene if not assigned in inspector settlementTeamLoader = FindAnyObjectByType(); } if (settlementTeamLoader != null) { // 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 ?? FindAnyObjectByType(); try { settlementTeamLoader.PopulateSettlementCards(); } catch (System.Exception ex) { Debug.LogWarning("Failed to PopulateSettlementCards: " + ex); } } // 初始化结算完成,在界面UI显示后 // 尝试选择 MVP 英雄的大图 SetMvpHeroImageFromTopScorer(); StartMusicTransition(); // --- 修改:在所有逻辑末尾开始 CanvasGroup 渐变 --- StartCanvasFadeIn(); } /// /// 初始化结算界面的 CanvasGroup 为透明状态 /// private void InitializeSettlementCanvas() { if (settlementCanvasGroup != null) { settlementCanvasGroup.alpha = 0f; settlementCanvasGroup.interactable = false; settlementCanvasGroup.blocksRaycasts = false; Debug.Log("[SettlementController] Settlement canvas initialized to transparent state"); } else { Debug.LogWarning("[SettlementController] settlementCanvasGroup is not assigned, cannot initialize"); } } // 缓存 AllyHero_SO 数组,避免在结算界面多次调用昂贵的 Resources.LoadAll private static AllyHero_SO[] _cachedAllyHeroSOs; /// /// 从所有dlcData中查找并准备当前歌曲所属DLC的结算音乐 /// private void PrepareSettlementMusic() { // --- 修改:移除 CanvasGroup 相关设置,已移动到结算逻辑末尾调用 --- if (thisSong_so == null) { Debug.LogWarning("[SettlementController] thisSong_so is null, cannot prepare settlement music"); return; } if (settlementAudioSource == null) { Debug.LogWarning("[SettlementController] settlementAudioSource is not assigned, cannot prepare settlement music"); return; } // 使用异步或分帧逻辑来查找 DLC StartCoroutine(PrepareSettlementMusicRoutine()); } private IEnumerator PrepareSettlementMusicRoutine() { // 加载 dlcData ScriptableObjects dlcData[] allDlcs = Resources.LoadAll(""); dlcData foundDlc = null; // 遍历所有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)) { 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}'"); yield break; } if (foundDlc.settlementMusic == null) { Debug.LogWarning($"[SettlementController] DLC '{foundDlc.dlcName}' does not have settlement music assigned"); yield break; } // 设置结算音乐的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}"); } /// /// 开始音乐过渡,将原游戏背景音乐淡出,然后播放结算音乐 /// private void StartMusicTransition() { if (musicTransitionCoroutine != null) { StopCoroutine(musicTransitionCoroutine); } musicTransitionCoroutine = StartCoroutine(MusicTransitionRoutine()); } /// /// 音乐过渡协程: /// 1. 将游戏音乐的低通滤波器从 22000Hz 逐渐降至 0Hz,同时音量降至 0 /// 2. 渐变完成后停止原音轨并开始播放结算音乐 /// private IEnumerator MusicTransitionRoutine() { float elapsed = 0f; 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"); 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"); } // 过渡完成后,开始播放结算音乐 if (settlementAudioSource != null && settlementAudioSource.clip != null) { try { settlementAudioSource.mute = false; 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) { Debug.LogWarning($"[SettlementController] Failed to start settlement music: {ex.Message}"); } } musicTransitionCoroutine = null; } /// /// 开始 CanvasGroup 渐入效果 /// private void StartCanvasFadeIn() { if (canvasFadeCoroutine != null) { StopCoroutine(canvasFadeCoroutine); } canvasFadeCoroutine = StartCoroutine(CanvasFadeInRoutine()); } /// /// CanvasGroup 渐入协程:0.25秒内从 alpha=0 渐变到 alpha=1 /// private IEnumerator CanvasFadeInRoutine() { if (settlementCanvasGroup == null) { Debug.LogWarning("[SettlementController] settlementCanvasGroup is not assigned, cannot fade in"); yield break; } float fadeDuration = 0.25f; float elapsed = 0f; float startAlpha = settlementCanvasGroup.alpha; float targetAlpha = 1f; Debug.Log($"[SettlementController] Starting CanvasGroup fade-in from {startAlpha} to {targetAlpha} over {fadeDuration}s"); while (elapsed < fadeDuration) { elapsed += Time.unscaledDeltaTime; float t = Mathf.Clamp01(elapsed / fadeDuration); settlementCanvasGroup.alpha = Mathf.Lerp(startAlpha, targetAlpha, t); yield return null; } // ȷ������״̬ settlementCanvasGroup.alpha = targetAlpha; settlementCanvasGroup.interactable = true; settlementCanvasGroup.blocksRaycasts = true; Debug.Log("[SettlementController] CanvasGroup fade-in complete"); canvasFadeCoroutine = null; } /// /// 重新开始当前游戏 - 重新加载场景并重置游戏状态 /// private void OnReplayButtonClicked() { Debug.Log("[SettlementController] Replay button clicked - restarting current game"); // 验证必要引用 if (bmm == null) { Debug.LogError("[SettlementController] BeatmapManager is null, cannot replay"); return; } if (bmm.assignedSongData == null) { Debug.LogError("[SettlementController] AssignedSongData is null, cannot replay"); return; } // 保存当前关卡信息用于重新加载 SongData songToReplay = bmm.assignedSongData; int difficultyToReplay = bmm.assignedDifficulty; if (difficultyToReplay < 0) { Debug.LogError("[SettlementController] AssignedDifficulty is invalid, cannot replay"); return; } Debug.Log($"[SettlementController] Reloading song: {songToReplay.songName}, difficulty: {difficultyToReplay}"); // 停止结算音乐 if (settlementAudioSource != null && settlementAudioSource.isPlaying) { settlementAudioSource.Stop(); } // 设置 BeatmapManager 为下一次加载准备 BeatmapManager.SetPendingSong(songToReplay, difficultyToReplay); // 重新加载当前场景 StartCoroutine(LoadSceneAsync(SceneManager.GetActiveScene().name)); } private IEnumerator LoadSceneAsync(string sceneName) { AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName); while (!asyncLoad.isDone) { yield return null; } } /// /// 返回选曲界面 /// 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; // Ensure time scale restored try { Time.timeScale = 1f; } catch {} // If GameManager and its blackMaskImage available, start coroutine on gm to fade to black then load if (gm != null && gm.blackMaskImage != null) { gm.StartCoroutine(FadeToBlackAndLoadOnGM("selectYourSongFirst", 0.25f)); } else { StartCoroutine(LoadSceneAsync("selectYourSongFirst")); } } // Coroutine that will be started on the GameManager instance so that the gm's MonoBehaviour runs it private IEnumerator FadeToBlackAndLoadOnGM(string sceneName, float duration) { if (gm == null || gm.blackMaskImage == null) { AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName); while (!asyncLoad.isDone) yield return null; yield break; } var blackMask = gm.blackMaskImage; // ensure image active if (!blackMask.gameObject.activeSelf) blackMask.gameObject.SetActive(true); float startA = blackMask.color.a; float elapsed = 0f; // enable raycast target while fading to block input try { blackMask.raycastTarget = true; } catch {} while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; float frac = Mathf.Clamp01(elapsed / Mathf.Max(0.0001f, duration)); Color c = blackMask.color; c.a = Mathf.Lerp(startA, 1f, frac); blackMask.color = c; yield return null; } // ensure fully opaque Color fc = blackMask.color; fc.a = 1f; blackMask.color = fc; // load target scene AsyncOperation asyncOp = SceneManager.LoadSceneAsync(sceneName); while (!asyncOp.isDone) { yield return null; } } /// /// 根据各角色(按槽位选出最高分的角色),设置 AllyHero_SO 中的 ally_hero_HD_image 赋值给 mvp_hero_hd_image /// 这里使用 ScoreManager 的 per-track pm sums,如果没有则从场景中的 AllyCombatant.currentScore 读取 /// private void SetMvpHeroImageFromTopScorer() { if (mvp_hero_hd_image == null) { Debug.LogWarning("[SettlementController] mvp_hero_hd_image is not assigned"); return; } int topIndex = -1; int[] scores = new int[5]; if (sm != null) { scores[0] = sm.red_pmScore_sum; scores[1] = sm.green_pmScore_sum; scores[2] = sm.yellow_pmScore_sum; scores[3] = sm.purple_pmScore_sum; scores[4] = sm.blue_pmScore_sum; } else { // fallback: read AllyCombatant.currentScore from scene for (int i = 0; i < 5; i++) { var go = GameObject.Find($"ally_0{ i+1 }"); if (go != null) { var ac = go.GetComponent(); scores[i] = ac != null ? ac.currentScore : 0; } else scores[i] = 0; } } int max = -1; for (int i = 0; i < scores.Length; i++) { if (scores[i] > max) { max = scores[i]; topIndex = i; } } if (topIndex < 0 || max <= 0) { Debug.Log("[SettlementController] No top scorer found or scores are all zero"); // hide image mvp_hero_hd_image.sprite = null; mvp_hero_hd_image.color = new Color(mvp_hero_hd_image.color.r, mvp_hero_hd_image.color.g, mvp_hero_hd_image.color.b, 0f); return; } // Try to resolve AllyHero_SO for the winning slot AllyHero_SO heroSO = null; // try SkillBuilder cache if (SkillBuilder.Instance != null) { try { heroSO = SkillBuilder.Instance.GetAllyHeroSOBySlot(topIndex); } catch { heroSO = null; } } // fallback: use teamUIController slot ids to find hero id -> load SO if (heroSO == null && teamUIController.Instance != null && teamUIController.Instance.allySlotIds != null) { int allyId = -1; if (topIndex >= 0 && topIndex < teamUIController.Instance.allySlotIds.Count) allyId = teamUIController.Instance.allySlotIds[topIndex]; if (allyId > 0) { if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0) { _cachedAllyHeroSOs = Resources.LoadAll(""); } foreach (var a in _cachedAllyHeroSOs) { if (a != null && a.ally_heroID == allyId) { heroSO = a; break; } } } } // final fallback: try direct Resources lookup by scanning all and picking first non-null for slot if (heroSO == null) { if (_cachedAllyHeroSOs == null || _cachedAllyHeroSOs.Length == 0) { _cachedAllyHeroSOs = Resources.LoadAll(""); } if (_cachedAllyHeroSOs != null && _cachedAllyHeroSOs.Length > 0) { // attempt to match by name or just pick first heroSO = _cachedAllyHeroSOs[0] as AllyHero_SO; } } if (heroSO != null && heroSO.ally_hero_HD_image != null) { mvp_hero_hd_image.sprite = heroSO.ally_hero_HD_image; mvp_hero_hd_image.color = new Color(mvp_hero_hd_image.color.r, mvp_hero_hd_image.color.g, mvp_hero_hd_image.color.b, 1f); Debug.Log($"[SettlementController] MVP assigned from slot {topIndex+1} with score {max}: {heroSO.ally_heroName}"); } else { mvp_hero_hd_image.sprite = null; mvp_hero_hd_image.color = new Color(mvp_hero_hd_image.color.r, mvp_hero_hd_image.color.g, mvp_hero_hd_image.color.b, 0f); Debug.LogWarning("[SettlementController] MVP SO or HD image not found"); } } }