超大量的更新 修复很多问题,gameplay特效初步
This commit is contained in:
@@ -8,6 +8,16 @@ public class ScoreManager : MonoBehaviour
|
||||
|
||||
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;
|
||||
@@ -42,6 +52,10 @@ public class ScoreManager : MonoBehaviour
|
||||
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;
|
||||
@@ -64,6 +78,8 @@ public class ScoreManager : MonoBehaviour
|
||||
public void ResetStatistics()
|
||||
{
|
||||
countPerfect = countGreat = countGood = countMiss = 0;
|
||||
perfectClearBonusPm = 0;
|
||||
perfectClearBonusApplied = false;
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
@@ -100,10 +116,212 @@ public class ScoreManager : MonoBehaviour
|
||||
|
||||
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;
|
||||
@@ -147,6 +365,7 @@ public class ScoreManager : MonoBehaviour
|
||||
/// </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;
|
||||
@@ -178,7 +397,8 @@ public class ScoreManager : MonoBehaviour
|
||||
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];
|
||||
allSum_pmScore = (int)Mathf.Min((float)aggPm, (float)int.MaxValue - 1f);
|
||||
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)
|
||||
@@ -215,6 +435,9 @@ public class ScoreManager : MonoBehaviour
|
||||
|
||||
// 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()
|
||||
|
||||
Reference in New Issue
Block a user