579 lines
23 KiB
C#
579 lines
23 KiB
C#
using UnityEngine;
|
|
using TMPro;
|
|
using UnityEngine.UI;
|
|
|
|
public class ScoreManager : MonoBehaviour
|
|
{
|
|
public static ScoreManager Instance { get; private set; }
|
|
|
|
public int totalScore = 0;
|
|
|
|
// Gameplay UI: per-track chart progress keys under bgSPRITE (Scale.y: 0%->0, 100%->2).
|
|
private readonly Transform[] _idolscoreKeys = new Transform[5];
|
|
private readonly Vector3[] _idolscoreKeyBaseScales = new Vector3[5];
|
|
private readonly bool[] _idolscoreKeyBaseScaleCached = new bool[5];
|
|
private readonly float[] _idolscoreDisplayY = new float[5];
|
|
private readonly float[] _idolscoreTargetY = new float[5];
|
|
private readonly float[] _idolscoreLastTargetY = new float[5];
|
|
private readonly float[] _idolscorePulseAmplitude = new float[5];
|
|
private readonly float[] _idolscorePulseSeed = new float[5];
|
|
|
|
// per-track pm score sums (red, green, yellow, purple, blue)
|
|
public int red_pmScore_sum = 0;
|
|
public int green_pmScore_sum = 0;
|
|
public int yellow_pmScore_sum = 0;
|
|
public int purple_pmScore_sum = 0;
|
|
public int blue_pmScore_sum = 0;
|
|
|
|
// aggregate of the five track pm sums
|
|
public int allSum_pmScore = 0;
|
|
|
|
private int[] pmScoreSums = new int[5];
|
|
|
|
// per-track idol score sums (red, green, yellow, purple, blue)
|
|
public int red_idolScore_sum = 0;
|
|
public int green_idolScore_sum = 0;
|
|
public int yellow_idolScore_sum = 0;
|
|
public int purple_idolScore_sum = 0;
|
|
public int blue_idolScore_sum = 0;
|
|
|
|
// aggregate of the five track idol sums
|
|
public int allSum_idolScore = 0;
|
|
|
|
private int[] idolScoreSums = new int[5];
|
|
|
|
private readonly int[] tmpCurrents = new int[5];
|
|
private readonly int[] tmpMaxes = new int[5];
|
|
|
|
private readonly GameObject[] allyObjects = new GameObject[5];
|
|
private readonly AllyCombatant[] allyCombatants = new AllyCombatant[5];
|
|
private int lastAllyCacheFrame = -9999;
|
|
|
|
private readonly TextMeshProUGUI[] slotTmpFallback = new TextMeshProUGUI[5];
|
|
private readonly Text[] slotLegacyFallback = new Text[5];
|
|
private readonly bool[] slotFallbackResolved = new bool[5];
|
|
private JudgeManager hookedJudgeManager;
|
|
private bool perfectBonusHooked = false;
|
|
private int perfectClearBonusPm = 0;
|
|
private bool perfectClearBonusApplied = false;
|
|
|
|
[Header("Judgement Statistics")]
|
|
public int countPerfect = 0;
|
|
public int countGreat = 0;
|
|
public int countGood = 0;
|
|
public int countMiss = 0;
|
|
|
|
[Header("Per-Track Judgement Statistics")]
|
|
public int[] trackPerfectCounts = new int[5];
|
|
public int[] trackGreatCounts = new int[5];
|
|
public int[] trackGoodCounts = new int[5];
|
|
public int[] trackMissCounts = new int[5];
|
|
|
|
[Header("Timing Statistics")]
|
|
public int countEarly = 0;
|
|
public int countLate = 0;
|
|
public float totalOffsetMs = 0f;
|
|
public int offsetCount = 0;
|
|
|
|
public void ResetStatistics()
|
|
{
|
|
countPerfect = countGreat = countGood = countMiss = 0;
|
|
perfectClearBonusPm = 0;
|
|
perfectClearBonusApplied = false;
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
trackPerfectCounts[i] = 0;
|
|
trackGreatCounts[i] = 0;
|
|
trackGoodCounts[i] = 0;
|
|
trackMissCounts[i] = 0;
|
|
}
|
|
|
|
countEarly = countLate = 0;
|
|
totalOffsetMs = 0f;
|
|
offsetCount = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Records a timing offset in milliseconds.
|
|
/// Positive = Early, Negative = Late.
|
|
/// </summary>
|
|
public void RecordOffset(float offsetMs)
|
|
{
|
|
if (float.IsNaN(offsetMs)) return;
|
|
|
|
totalOffsetMs += offsetMs;
|
|
offsetCount++;
|
|
|
|
if (offsetMs > 0) countEarly++;
|
|
else if (offsetMs < 0) countLate++;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (Instance == null) Instance = this;
|
|
else Destroy(gameObject);
|
|
|
|
for (int i = 0; i < pmScoreSums.Length; i++) pmScoreSums[i] = 0;
|
|
for (int i = 0; i < idolScoreSums.Length; i++) idolScoreSums[i] = 0;
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
_idolscoreDisplayY[i] = 0f;
|
|
_idolscoreTargetY[i] = 0f;
|
|
_idolscoreLastTargetY[i] = 0f;
|
|
_idolscorePulseAmplitude[i] = 0f;
|
|
_idolscorePulseSeed[i] = UnityEngine.Random.Range(0.01f, 999f);
|
|
}
|
|
|
|
ResetStatistics();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
TryHookPerfectBonusEvent();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
UnhookPerfectBonusEvent();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
UnhookPerfectBonusEvent();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
// Ensure the progress keys start at 0.
|
|
UpdateIdolscoreKeyScales();
|
|
TryHookPerfectBonusEvent();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
EnsureIdolscoreKeys();
|
|
|
|
float dt = Time.unscaledDeltaTime;
|
|
if (dt <= 0f) return;
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
Transform t = _idolscoreKeys[i];
|
|
if (t == null) continue;
|
|
|
|
Vector3 baseScale = _idolscoreKeyBaseScaleCached[i] ? _idolscoreKeyBaseScales[i] : t.localScale;
|
|
float targetY = Mathf.Max(0f, _idolscoreTargetY[i]);
|
|
|
|
// Fast rise, slow settle.
|
|
float smooth = 1f - Mathf.Exp(-7.5f * dt);
|
|
_idolscoreDisplayY[i] = Mathf.Lerp(_idolscoreDisplayY[i], targetY, smooth);
|
|
|
|
// Random growth wobble when target updates.
|
|
_idolscorePulseAmplitude[i] = Mathf.Lerp(_idolscorePulseAmplitude[i], 0f, 4.8f * dt);
|
|
float noise = (Mathf.PerlinNoise(_idolscorePulseSeed[i], Time.unscaledTime * 7f) - 0.5f) * 2f;
|
|
float y = Mathf.Max(0f, _idolscoreDisplayY[i] + noise * _idolscorePulseAmplitude[i]);
|
|
|
|
t.localScale = new Vector3(baseScale.x, y, baseScale.z);
|
|
}
|
|
}
|
|
|
|
private void TryHookPerfectBonusEvent()
|
|
{
|
|
if (!Application.isPlaying) return;
|
|
|
|
if (perfectBonusHooked)
|
|
{
|
|
if (hookedJudgeManager != null) return;
|
|
// previous JudgeManager got destroyed across scene switch
|
|
perfectBonusHooked = false;
|
|
}
|
|
|
|
var jm = JudgeManager.Instance ?? UnityEngine.Object.FindAnyObjectByType<JudgeManager>();
|
|
if (jm == null) return;
|
|
|
|
jm.AllNotesJudged -= OnAllNotesJudgedForPerfectBonus;
|
|
jm.AllNotesJudged += OnAllNotesJudgedForPerfectBonus;
|
|
hookedJudgeManager = jm;
|
|
perfectBonusHooked = true;
|
|
}
|
|
|
|
private void UnhookPerfectBonusEvent()
|
|
{
|
|
if (!perfectBonusHooked) return;
|
|
if (hookedJudgeManager != null)
|
|
{
|
|
hookedJudgeManager.AllNotesJudged -= OnAllNotesJudgedForPerfectBonus;
|
|
}
|
|
hookedJudgeManager = null;
|
|
perfectBonusHooked = false;
|
|
}
|
|
|
|
private int GetCurrentChartLogicalNoteCount()
|
|
{
|
|
var bmm = UnityEngine.Object.FindAnyObjectByType<BeatmapManager>();
|
|
if (bmm != null)
|
|
{
|
|
if (bmm.beatmap != null && bmm.beatmap.notes != null && bmm.beatmap.notes.Length > 0)
|
|
return bmm.beatmap.notes.Length;
|
|
if (bmm.parsedNoteAmount > 0)
|
|
return bmm.parsedNoteAmount;
|
|
}
|
|
|
|
// Fallback to runtime judged count if beatmap reference is unavailable.
|
|
return countPerfect + countGreat + countGood + countMiss;
|
|
}
|
|
|
|
private int GetCurrentChartLeftoverScore()
|
|
{
|
|
var bmm = UnityEngine.Object.FindAnyObjectByType<BeatmapManager>();
|
|
if (bmm == null) return 0;
|
|
return Mathf.Max(0, bmm.leftoverScore);
|
|
}
|
|
|
|
private void OnAllNotesJudgedForPerfectBonus()
|
|
{
|
|
if (perfectClearBonusApplied) return;
|
|
|
|
int noteCount = Mathf.Max(0, GetCurrentChartLogicalNoteCount());
|
|
bool allPerfect = noteCount > 0 &&
|
|
countGreat == 0 &&
|
|
countGood == 0 &&
|
|
countMiss == 0 &&
|
|
countPerfect >= noteCount;
|
|
|
|
if (allPerfect)
|
|
{
|
|
perfectClearBonusPm = GetCurrentChartLeftoverScore();
|
|
}
|
|
else
|
|
{
|
|
perfectClearBonusPm = 0;
|
|
}
|
|
perfectClearBonusApplied = true;
|
|
|
|
long aggPm = 0;
|
|
long aggIdol = 0;
|
|
for (int i = 0; i < pmScoreSums.Length; i++) aggPm += pmScoreSums[i];
|
|
for (int i = 0; i < idolScoreSums.Length; i++) aggIdol += idolScoreSums[i];
|
|
|
|
long aggPmWithBonus = aggPm + (long)perfectClearBonusPm;
|
|
allSum_pmScore = (int)Mathf.Min((float)aggPmWithBonus, (float)int.MaxValue - 1f);
|
|
allSum_idolScore = (int)Mathf.Min((float)aggIdol, (float)int.MaxValue - 1f);
|
|
|
|
var ui = teamUIController.Instance;
|
|
if (ui != null)
|
|
{
|
|
if (ui.allSum_pmScore != null) ui.allSum_pmScore.text = allSum_pmScore.ToString();
|
|
if (ui.allSum_idolScore != null) ui.allSum_idolScore.text = allSum_idolScore.ToString();
|
|
}
|
|
|
|
RecalculateTotal();
|
|
}
|
|
|
|
private void EnsureIdolscoreKeys()
|
|
{
|
|
// Try to resolve missing refs (GameObject.Find doesn't return inactive objects).
|
|
if (_idolscoreKeys[0] == null) _idolscoreKeys[0] = GameObject.Find("idolscoreKey_red")?.transform;
|
|
if (_idolscoreKeys[1] == null) _idolscoreKeys[1] = GameObject.Find("idolscoreKey_green")?.transform;
|
|
if (_idolscoreKeys[2] == null) _idolscoreKeys[2] = GameObject.Find("idolscoreKey_yellow")?.transform;
|
|
if (_idolscoreKeys[3] == null) _idolscoreKeys[3] = GameObject.Find("idolscoreKey_purple")?.transform;
|
|
if (_idolscoreKeys[4] == null) _idolscoreKeys[4] = GameObject.Find("idolscoreKey_blue")?.transform;
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
var t = _idolscoreKeys[i];
|
|
if (t == null) continue;
|
|
if (_idolscoreKeyBaseScaleCached[i]) continue;
|
|
_idolscoreKeyBaseScales[i] = t.localScale;
|
|
_idolscoreKeyBaseScaleCached[i] = true;
|
|
}
|
|
}
|
|
|
|
private void UpdateIdolscoreKeyScales()
|
|
{
|
|
EnsureIdolscoreKeys();
|
|
EnsureAllyCache();
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
var t = _idolscoreKeys[i];
|
|
if (t == null) continue;
|
|
|
|
int maxScore = 0;
|
|
var ally = allyCombatants[i];
|
|
if (ally != null) maxScore = Mathf.Max(0, ally.maxTrackScore);
|
|
|
|
int curScore = pmScoreSums[i];
|
|
float ratio = maxScore > 0 ? (float)curScore / maxScore : 0f;
|
|
ratio = Mathf.Clamp01(ratio);
|
|
|
|
float targetY = ratio * 2f;
|
|
_idolscoreTargetY[i] = targetY;
|
|
|
|
if (Mathf.Abs(_idolscoreLastTargetY[i] - targetY) > 0.0001f)
|
|
{
|
|
_idolscoreLastTargetY[i] = targetY;
|
|
_idolscorePulseAmplitude[i] = UnityEngine.Random.Range(0.08f, 0.24f);
|
|
}
|
|
|
|
if (targetY <= 0.001f)
|
|
_idolscoreDisplayY[i] = 0f;
|
|
}
|
|
}
|
|
|
|
private void EnsureAllyCache()
|
|
{
|
|
int frame = Time.frameCount;
|
|
if (frame - lastAllyCacheFrame < 30) return;
|
|
lastAllyCacheFrame = frame;
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
if (allyCombatants[i] != null) continue;
|
|
|
|
var go = allyObjects[i];
|
|
if (go == null)
|
|
{
|
|
go = GameObject.Find($"ally_0{i + 1}");
|
|
allyObjects[i] = go;
|
|
}
|
|
if (go != null)
|
|
{
|
|
allyCombatants[i] = go.GetComponent<AllyCombatant>();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ResolveSlotFallbackUi(int slotIndex, GameObject parent)
|
|
{
|
|
if (slotIndex < 0 || slotIndex >= 5) return;
|
|
if (slotFallbackResolved[slotIndex]) return;
|
|
if (parent == null) return;
|
|
|
|
slotTmpFallback[slotIndex] = parent.GetComponentInChildren<TextMeshProUGUI>(true);
|
|
if (slotTmpFallback[slotIndex] == null)
|
|
{
|
|
slotLegacyFallback[slotIndex] = parent.GetComponentInChildren<Text>(true);
|
|
}
|
|
slotFallbackResolved[slotIndex] = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a per-note pm score delta to the specified track (0..4) and update named fields + aggregate.
|
|
/// Also calculates idol score as pmDelta * scoreEfficiency.
|
|
/// </summary>
|
|
public void AddPmScoreForTrack(int trackIndex, int pmDelta, float scoreEfficiency)
|
|
{
|
|
TryHookPerfectBonusEvent();
|
|
if (trackIndex < 0 || trackIndex >= pmScoreSums.Length) return;
|
|
if (pmDelta == 0) return;
|
|
pmScoreSums[trackIndex] += pmDelta;
|
|
// clamp at int.MaxValue-1 to avoid overflow
|
|
if (pmScoreSums[trackIndex] < 0) pmScoreSums[trackIndex] = 0;
|
|
if (pmScoreSums[trackIndex] > int.MaxValue - 1) pmScoreSums[trackIndex] = int.MaxValue - 1;
|
|
|
|
// calculate idol score: pmDelta * scoreEfficiency
|
|
int idolDelta = Mathf.FloorToInt(pmDelta * scoreEfficiency);
|
|
idolScoreSums[trackIndex] += idolDelta;
|
|
if (idolScoreSums[trackIndex] < 0) idolScoreSums[trackIndex] = 0;
|
|
if (idolScoreSums[trackIndex] > int.MaxValue - 1) idolScoreSums[trackIndex] = int.MaxValue - 1;
|
|
|
|
// update named fields for easy access
|
|
red_pmScore_sum = pmScoreSums[0];
|
|
green_pmScore_sum = pmScoreSums[1];
|
|
yellow_pmScore_sum = pmScoreSums[2];
|
|
purple_pmScore_sum = pmScoreSums[3];
|
|
blue_pmScore_sum = pmScoreSums[4];
|
|
|
|
red_idolScore_sum = idolScoreSums[0];
|
|
green_idolScore_sum = idolScoreSums[1];
|
|
yellow_idolScore_sum = idolScoreSums[2];
|
|
purple_idolScore_sum = idolScoreSums[3];
|
|
blue_idolScore_sum = idolScoreSums[4];
|
|
|
|
// recompute aggregates
|
|
long aggPm = 0;
|
|
long aggIdol = 0;
|
|
for (int i = 0; i < pmScoreSums.Length; i++) aggPm += pmScoreSums[i];
|
|
for (int i = 0; i < idolScoreSums.Length; i++) aggIdol += idolScoreSums[i];
|
|
long aggPmWithBonus = aggPm + (long)perfectClearBonusPm;
|
|
allSum_pmScore = (int)Mathf.Min((float)aggPmWithBonus, (float)int.MaxValue - 1f);
|
|
allSum_idolScore = (int)Mathf.Min((float)aggIdol, (float)int.MaxValue - 1f);
|
|
|
|
if (JudgeManager.IsDebugEnabled)
|
|
Debug.Log($"[ScoreManager] Added {pmDelta} to track {trackIndex} pm sum, idol delta {idolDelta}. New pm sums: R{red_pmScore_sum} G{green_pmScore_sum} Y{yellow_pmScore_sum} P{purple_pmScore_sum} B{blue_pmScore_sum} -> allSumPm={allSum_pmScore}. Idol sums: R{red_idolScore_sum} G{green_idolScore_sum} Y{yellow_idolScore_sum} P{purple_idolScore_sum} B{blue_idolScore_sum} -> allSumIdol={allSum_idolScore}");
|
|
|
|
// Update UI in teamUIController if available (per-track pm sums + aggregate)
|
|
var ui = teamUIController.Instance;
|
|
if (ui != null)
|
|
{
|
|
// Legacy Text fields on teamUIController
|
|
try
|
|
{
|
|
if (ui.red_pmScore_sum != null) ui.red_pmScore_sum.text = red_pmScore_sum.ToString();
|
|
if (ui.green_pmScore_sum != null) ui.green_pmScore_sum.text = green_pmScore_sum.ToString();
|
|
if (ui.yellow_pmScore_sum != null) ui.yellow_pmScore_sum.text = yellow_pmScore_sum.ToString();
|
|
if (ui.purple_pmScore_sum != null) ui.purple_pmScore_sum.text = purple_pmScore_sum.ToString();
|
|
if (ui.blue_pmScore_sum != null) ui.blue_pmScore_sum.text = blue_pmScore_sum.ToString();
|
|
if (ui.allSum_pmScore != null) ui.allSum_pmScore.text = allSum_pmScore.ToString();
|
|
|
|
if (ui.red_idolScore_sum != null) ui.red_idolScore_sum.text = red_idolScore_sum.ToString();
|
|
if (ui.green_idolScore_sum != null) ui.green_idolScore_sum.text = green_idolScore_sum.ToString();
|
|
if (ui.yellow_idolScore_sum != null) ui.yellow_idolScore_sum.text = yellow_idolScore_sum.ToString();
|
|
if (ui.purple_idolScore_sum != null) ui.purple_idolScore_sum.text = purple_idolScore_sum.ToString();
|
|
if (ui.blue_idolScore_sum != null) ui.blue_idolScore_sum.text = blue_idolScore_sum.ToString();
|
|
if (ui.allSum_idolScore != null) ui.allSum_idolScore.text = allSum_idolScore.ToString();
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
if (JudgeManager.IsDebugEnabled) Debug.LogWarning($"[ScoreManager] Failed to write sums to teamUIController fields: {ex}");
|
|
}
|
|
}
|
|
|
|
// Optionally update any UI for pm sums here if teamUIController exposes fields (not implemented by default)
|
|
|
|
// Ensure total is recalculated when pm/idol aggregates change so totalScore reflects pm + idol
|
|
RecalculateTotal();
|
|
|
|
// Update per-track progress keys (bgSPRITE/idolscoreKey_*).
|
|
UpdateIdolscoreKeyScales();
|
|
}
|
|
|
|
public void RecalculateTotal()
|
|
{
|
|
EnsureAllyCache();
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
var ally = allyCombatants[i];
|
|
if (ally != null)
|
|
{
|
|
tmpCurrents[i] = ally.currentScore;
|
|
tmpMaxes[i] = ally.maxTrackScore;
|
|
}
|
|
else
|
|
{
|
|
tmpCurrents[i] = 0;
|
|
tmpMaxes[i] = 0;
|
|
}
|
|
}
|
|
|
|
// totalScore should include both pm (per-note) and idol aggregates maintained by ScoreManager
|
|
long combined = (long)allSum_pmScore + (long)allSum_idolScore;
|
|
// clamp to int range
|
|
totalScore = (int)Mathf.Min((float)combined, (float)int.MaxValue - 1f);
|
|
|
|
// update UI if available
|
|
if (teamUIController.Instance != null)
|
|
{
|
|
var ui = teamUIController.Instance;
|
|
|
|
// helper lambda to set text on TMP or legacy Text under a parent fallback
|
|
void SetScoreText(TextMeshProUGUI assignedTmp, GameObject parent, int cur, int max, string slotName)
|
|
{
|
|
string value = cur + "/" + max;
|
|
if (assignedTmp != null)
|
|
{
|
|
assignedTmp.text = value;
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote to assigned TMP for {slotName}: '{value}' -> {assignedTmp.gameObject.name}");
|
|
return;
|
|
}
|
|
if (parent != null)
|
|
{
|
|
int idx = slotName == "teammate01" ? 0 :
|
|
slotName == "teammate02" ? 1 :
|
|
slotName == "teammate03" ? 2 :
|
|
slotName == "teammate04" ? 3 :
|
|
slotName == "teammate05" ? 4 : -1;
|
|
|
|
if (idx >= 0)
|
|
{
|
|
ResolveSlotFallbackUi(idx, parent);
|
|
var tmp = slotTmpFallback[idx];
|
|
if (tmp != null)
|
|
{
|
|
tmp.text = value;
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote to TMP in parent {parent.name} for {slotName}: '{value}' -> {tmp.gameObject.name}");
|
|
return;
|
|
}
|
|
var legacy = slotLegacyFallback[idx];
|
|
if (legacy != null)
|
|
{
|
|
legacy.text = value;
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote to legacy Text in parent {parent.name} for {slotName}: '{value}' -> {legacy.gameObject.name}");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var tmp = parent.GetComponentInChildren<TextMeshProUGUI>(true);
|
|
if (tmp != null)
|
|
{
|
|
tmp.text = value;
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote to TMP in parent {parent.name} for {slotName}: '{value}' -> {tmp.gameObject.name}");
|
|
return;
|
|
}
|
|
var legacy = parent.GetComponentInChildren<Text>(true);
|
|
if (legacy != null)
|
|
{
|
|
legacy.text = value;
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote to legacy Text in parent {parent.name} for {slotName}: '{value}' -> {legacy.gameObject.name}");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (JudgeManager.IsDebugEnabled) Debug.LogWarning($"[ScoreManager] Could not find UI to write score for {slotName}. assignedTmp is null and parent '{parent?.name}' has no TMP/Text children.");
|
|
}
|
|
|
|
// Update each slot: use the explicit TMP fields if set; otherwise try parent object fields
|
|
SetScoreText(ui.teammate01_current_scoreText, ui.objectFather_ally01, tmpCurrents[0], tmpMaxes[0], "teammate01");
|
|
SetScoreText(ui.teammate02_current_scoreText, ui.objectFather_ally02, tmpCurrents[1], tmpMaxes[1], "teammate02");
|
|
SetScoreText(ui.teammate03_current_scoreText, ui.objectFather_ally03, tmpCurrents[2], tmpMaxes[2], "teammate03");
|
|
SetScoreText(ui.teammate04_current_scoreText, ui.objectFather_ally04, tmpCurrents[3], tmpMaxes[3], "teammate04");
|
|
SetScoreText(ui.teammate05_current_scoreText, ui.objectFather_ally05, tmpCurrents[4], tmpMaxes[4], "teammate05");
|
|
|
|
// update total score (try TMP first, then legacy Text)
|
|
if (ui.currentTotalScore != null)
|
|
{
|
|
var go = ui.currentTotalScore.gameObject;
|
|
if (go != null)
|
|
{
|
|
var tmpComp = go.GetComponent<TextMeshProUGUI>();
|
|
if (tmpComp != null)
|
|
{
|
|
tmpComp.text = totalScore.ToString();
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote total to TMP: {totalScore} -> {tmpComp.gameObject.name}");
|
|
}
|
|
else
|
|
{
|
|
var legacyComp = go.GetComponent<Text>();
|
|
if (legacyComp != null)
|
|
{
|
|
legacyComp.text = totalScore.ToString();
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote total to legacy Text: {totalScore} -> {legacyComp.gameObject.name}");
|
|
}
|
|
else
|
|
{
|
|
ui.currentTotalScore.text = totalScore.ToString(); // fallback
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote total to currentTotalScore field fallback: {totalScore}");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ui.currentTotalScore.text = totalScore.ToString();
|
|
if (JudgeManager.IsDebugEnabled) Debug.Log($"[ScoreManager] Wrote total to currentTotalScore fallback (no go): {totalScore}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (JudgeManager.IsDebugEnabled) Debug.LogWarning("[ScoreManager] teamUIController.currentTotalScore is null; cannot display total score.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (JudgeManager.IsDebugEnabled) Debug.LogWarning("[ScoreManager] teamUIController.Instance is null; cannot update UI.");
|
|
}
|
|
}
|
|
}
|