Files
bansonic_beta_main/Assets/scripts/gamePlay_gameplay/settlementController.cs
T

800 lines
28 KiB
C#

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("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("Inspector")]
public Button exit_toSelectSongs;
public Button replay_thisGame;
public Button display_rankList;
public Button share_toSocialMedia;
[Header("Text And Progress")]
public Text songName_Text;
[Tooltip("Documentation text normalized.")]
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("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("Inspector")]
public Text reward_playerEXP_Text;
public Text reward_money_Text;
public Text reward_idolEXP_bottle_Text;
[Header("Inspector")]
public loadSettlementTeamPrefab settlementTeamLoader;
public Image mvp_hero_hd_image;
[Header("Inspector")]
[SerializeField] private long moneyToGive_thisLevel;
// Documentation text normalized.
[Header("Inspector")]
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("Inspector")]
[Tooltip("Settlement background music clip used during the settlement flow.")]
public AudioSource settlementAudioSource;
[Tooltip("Original gameplay music source (usually the chart song). ")]
public AudioSource oriGameMusicSource;
[Tooltip("Documentation text normalized.")]
public AudioMixer gameMusicMixer;
[Tooltip("Documentation text normalized.")]
public string lowpassParamName = "inGameMusic_lowpass";
[Tooltip("Duration of lowpass transition in seconds.")]
public float lowpassFadeDuration = 2f;
[Tooltip("Settlement CanvasGroup used for fade-in.")]
public CanvasGroup settlementCanvasGroup;
[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);
}
if (exit_toSelectSongs != null)
{
exit_toSelectSongs.onClick.AddListener(OnExitButtonClicked);
}
// Documentation text normalized.
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()
{
// Documentation text normalized.
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);
}
// Documentation text normalized.
if (musicTransitionCoroutine != null)
{
StopCoroutine(musicTransitionCoroutine);
musicTransitionCoroutine = null;
}
// Documentation text normalized.
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()
{
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);
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<GameManager>(); if (activeGM != null) activeGM.RecordTotalPlayTime(); }
// Documentation text normalized.
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) / _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;
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;
thisSong_so.ApplySettlementResult(diff, pm, idol, _1000000);
}
}
// 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<loadSettlementTeamPrefab>();
}
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<GameManager>();
try { settlementTeamLoader.PopulateSettlementCards(); }
catch (System.Exception ex) { Debug.LogWarning("Failed to PopulateSettlementCards: " + ex); }
}
// Documentation text normalized.
// Documentation text normalized.
SetMvpHeroImageFromTopScorer();
StartMusicTransition();
// Documentation text normalized.
StartCanvasFadeIn();
}
/// <summary>
/// Documentation text normalized.
/// </summary>
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");
}
}
// Documentation text normalized.
private static AllyHero_SO[] _cachedAllyHeroSOs;
/// <summary>
/// Documentation text normalized.
/// </summary>
private void PrepareSettlementMusic()
{
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;
}
dlcData[] allDlcs = Resources.LoadAll<dlcData>("");
dlcData foundDlc = null;
for (int i = 0; i < allDlcs.Length; i++)
{
dlcData dlc = allDlcs[i];
if (dlc == null || dlc.songList == null) continue;
if (!dlc.songList.Contains(thisSong_so)) continue;
foundDlc = dlc;
break;
}
if (foundDlc == null)
{
Debug.LogWarning($"[SettlementController] No DLC found containing song '{thisSong_so.songName}'");
return;
}
if (foundDlc.settlementMusic == null)
{
Debug.LogWarning($"[SettlementController] DLC '{foundDlc.dlcName}' does not have settlement music assigned");
return;
}
bool clipChanged = settlementAudioSource.clip != foundDlc.settlementMusic;
if (clipChanged)
{
settlementAudioSource.Stop();
settlementAudioSource.clip = foundDlc.settlementMusic;
settlementAudioSource.time = 0f;
}
settlementAudioSource.loop = true;
settlementAudioSource.playOnAwake = false;
settlementAudioSource.volume = 1f;
settlementAudioSource.mute = false;
Debug.Log($"[SettlementController] Prepared settlement music from DLC '{foundDlc.dlcName}': {foundDlc.settlementMusic.name}");
}
/// <summary>
/// Documentation text normalized.
/// </summary>
private void StartMusicTransition()
{
if (musicTransitionCoroutine != null)
{
StopCoroutine(musicTransitionCoroutine);
}
musicTransitionCoroutine = StartCoroutine(MusicTransitionRoutine());
}
/// <summary>
/// Documentation text normalized.
/// Documentation text normalized.
/// Documentation text normalized.
/// </summary>
private IEnumerator MusicTransitionRoutine()
{
float elapsed = 0f;
float transitionDuration = Mathf.Max(0.01f, lowpassFadeDuration);
float startVolume = (oriGameMusicSource != null) ? oriGameMusicSource.volume : 1f;
bool settlementMusicStarted = false;
float settlementStartVolume = 0f;
// 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}");
}
catch (System.Exception ex)
{
Debug.LogWarning($"[SettlementController] Failed to start settlement music: {ex.Message}");
}
}
musicTransitionCoroutine = null;
}
/// <summary>
/// Documentation text normalized.
/// </summary>
private void StartCanvasFadeIn()
{
if (canvasFadeCoroutine != null)
{
StopCoroutine(canvasFadeCoroutine);
}
canvasFadeCoroutine = StartCoroutine(CanvasFadeInRoutine());
}
/// <summary>
/// Documentation text normalized.
/// </summary>
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;
}
// Documentation text normalized.
settlementCanvasGroup.alpha = targetAlpha;
settlementCanvasGroup.interactable = true;
settlementCanvasGroup.blocksRaycasts = true;
Debug.Log("[SettlementController] CanvasGroup fade-in complete");
canvasFadeCoroutine = null;
}
/// <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");
return;
}
if (bmm.assignedSongData == null)
{
Debug.LogError("[SettlementController] AssignedSongData is null, cannot replay");
return;
}
// Documentation text normalized.
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}");
// Documentation text normalized.
if (settlementAudioSource != null && settlementAudioSource.isPlaying)
{
settlementAudioSource.Stop();
}
// Documentation text normalized.
BeatmapManager.SetPendingSong(songToReplay, difficultyToReplay);
// Documentation text normalized.
StartCoroutine(LoadSceneAsync(SceneManager.GetActiveScene().name));
}
private IEnumerator LoadSceneAsync(string sceneName)
{
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
while (!asyncLoad.isDone)
{
yield return null;
}
}
/// <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;
// 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;
}
}
/// <summary>
/// Documentation text normalized.
/// Documentation text normalized.
/// </summary>
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<AllyCombatant>();
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<AllyHero_SO>("");
}
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<AllyHero_SO>("");
}
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");
}
}
}