改动与优化

This commit is contained in:
FloatGaming
2026-07-20 22:19:25 +08:00
parent 0a0872c4f4
commit b5d1cdcbc5
83 changed files with 2475 additions and 276 deletions
@@ -134,6 +134,8 @@ public class settlementController : MonoBehaviour
[SerializeField] private float introMoveDuration = 0.42f;
[SerializeField] private float introNumberDuration = 0.48f;
[SerializeField] private float introStepGap = 0.06f;
[SerializeField] private float introStaticElementDuration = 0.22f;
[SerializeField] private float introBarFillDuration = 0.36f;
[SerializeField] private float introMvpEnterYOffset = 120f;
[SerializeField] private float introMvpEnterDuration = 0.42f;
[SerializeField] private Ease introMvpEnterEase = Ease.OutCubic;
@@ -142,6 +144,7 @@ public class settlementController : MonoBehaviour
[Header("Settle Rewards")]
public GameObject rewardPrefab;
public Transform rewardParent;
private Coroutine settlementRewardLayoutRefreshRoutine;
private int targetPmScore;
private int targetIdolScore;
@@ -157,6 +160,11 @@ public class settlementController : MonoBehaviour
private float targetGreatPercent;
private float targetGoodPercent;
private float targetMissPercent;
private int targetEarlyCount;
private int targetLateCount;
private float targetAvgOffsetMs;
private string targetGameNoteRateText = string.Empty;
private string targetPersonalRecordText = string.Empty;
private Tween mvpEntryTween;
private bool skipIntroRequested;
private Transform cachedIntroMvpTransform;
@@ -647,20 +655,25 @@ public class settlementController : MonoBehaviour
accuracy_Text.text = targetAccuracyPercent.ToString("F1") + "%";
// Timing Statistics
if (earlyHitCount_Text != null) earlyHitCount_Text.text = sm.countEarly.ToString();
if (lateHitCount_Text != null) lateHitCount_Text.text = sm.countLate.ToString();
targetEarlyCount = sm.countEarly;
targetLateCount = sm.countLate;
if (earlyHitCount_Text != null) earlyHitCount_Text.text = targetEarlyCount.ToString();
if (lateHitCount_Text != null) lateHitCount_Text.text = targetLateCount.ToString();
if (avgOffset_Text != null)
{
float avg = sm.offsetCount > 0 ? sm.totalOffsetMs / sm.offsetCount : 0f;
avgOffset_Text.text = avg.ToString("F2") + " ms";
targetAvgOffsetMs = avg;
avgOffset_Text.text = targetAvgOffsetMs.ToString("F2") + " ms";
}
targetGameNoteRateText = gameNote_rate != null ? gameNote_rate.text : string.Empty;
TrySubmitArenaRoomScore();
}
else Debug.LogError("score manager is null");
// --- Achievement System: Load and display achievements ---
if (InGamePerformanceManager.Instance != null && !GameConfig.autoPlayEnabled)
if (InGamePerformanceManager.Instance != null)
{
// Calculate total cure, damage and mana from teamUIController
float totalCure = 0;
@@ -723,7 +736,8 @@ public class settlementController : MonoBehaviour
if (personalRecord_Text != null)
{
int currentRecord = thisSong_so.personalRecord;
personalRecord_Text.text = currentRecord.ToString();
targetPersonalRecordText = currentRecord.ToString();
personalRecord_Text.text = targetPersonalRecordText;
// If current total score broke the overall personal record (all difficulties)
// and we are NOT in autoplay (since we didn't save the result in autoplay)
@@ -846,6 +860,7 @@ public class settlementController : MonoBehaviour
SpawnSettlementReward(global::rewardPrefab.RewardVisualType.Coins, coinReward);
SpawnSettlementReward(global::rewardPrefab.RewardVisualType.Material, materialReward);
SpawnSettlementReward(global::rewardPrefab.RewardVisualType.PlayerExp, playerExpReward);
RequestSettlementRewardLayoutRebuild();
}
private void SpawnSettlementReward(global::rewardPrefab.RewardVisualType rewardType, int amount)
@@ -861,6 +876,50 @@ public class settlementController : MonoBehaviour
{
prefab.Bind(rewardType, amount);
}
UI_OrderedEntryAnimator.PlayFadeOnly(go, rewardParent != null ? rewardParent.childCount - 1 : 0, 0.2f, 0.035f, false);
}
private void RequestSettlementRewardLayoutRebuild()
{
if (rewardParent == null)
{
return;
}
if (settlementRewardLayoutRefreshRoutine != null)
{
StopCoroutine(settlementRewardLayoutRefreshRoutine);
settlementRewardLayoutRefreshRoutine = null;
}
if (isActiveAndEnabled)
{
settlementRewardLayoutRefreshRoutine = StartCoroutine(RebuildSettlementRewardLayoutNextFrame());
return;
}
RebuildSettlementRewardLayoutNow();
}
private IEnumerator RebuildSettlementRewardLayoutNextFrame()
{
yield return null;
RebuildSettlementRewardLayoutNow();
settlementRewardLayoutRefreshRoutine = null;
}
private void RebuildSettlementRewardLayoutNow()
{
RectTransform rect = rewardParent as RectTransform;
if (rect == null)
{
return;
}
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(rect);
Canvas.ForceUpdateCanvases();
}
private static Player_SO LoadDefaultPlayerSo()
@@ -1164,6 +1223,20 @@ public class settlementController : MonoBehaviour
if (orderedGroups[i] != null) SetCanvasAlpha(orderedGroups[i], 0f);
}
PrepareStaticSettlementElement(thisSong_backPic != null ? thisSong_backPic.transform : null);
PrepareStaticSettlementElement(songName_Text != null ? songName_Text.transform : null);
PrepareStaticSettlementElement(finalLevel_img != null ? finalLevel_img.transform : null);
PrepareStaticSettlementElement(personalRecord_Text != null ? personalRecord_Text.transform : null);
PrepareStaticSettlementElement(gameNote_rate != null ? gameNote_rate.transform : null);
PrepareStaticSettlementElement(earlyHitCount_Text != null ? earlyHitCount_Text.transform : null);
PrepareStaticSettlementElement(lateHitCount_Text != null ? lateHitCount_Text.transform : null);
PrepareStaticSettlementElement(avgOffset_Text != null ? avgOffset_Text.transform : null);
PrepareImageFill(thisLevel_progressBar_Image);
PrepareImageFill(perfect_barFill_Image);
PrepareImageFill(great_barFill_Image);
PrepareImageFill(good_barFill_Image);
PrepareImageFill(miss_barFill_Image);
PrepareTextForCountUp(pmScoreSum_Text, false, 0);
PrepareTextForCountUp(idolScoreSum_Text, false, 0);
PrepareTextForCountUp(accuracy_Text, true, 0f, "F1");
@@ -1188,6 +1261,8 @@ public class settlementController : MonoBehaviour
// left/pics/quhuiImage flash
if (quhuiImageTr != null)
yield return StartCoroutine(FlashInTransform(quhuiImageTr, introFlashCount, introFlashDuration));
yield return StartCoroutine(FlashInTransform(thisSong_backPic != null ? thisSong_backPic.transform : null, 1, introStaticElementDuration));
yield return StartCoroutine(FlashInTransform(songName_Text != null ? songName_Text.transform : null, 1, introStaticElementDuration));
// score_bottom + shenstars move in together
Coroutine scoreBottomIn = null;
@@ -1215,12 +1290,21 @@ public class settlementController : MonoBehaviour
yield return WaitRealtime(introNumberDuration + 0.02f);
yield return StartCoroutine(FlashInTransform(finalScore_Text != null ? finalScore_Text.transform : null, introFlashCount, introFlashDuration * 0.9f));
yield return StartCoroutine(FlashInTransform(thisLevel_currentPercentage_Text != null ? thisLevel_currentPercentage_Text.transform : null, introFlashCount, introFlashDuration * 0.9f));
yield return StartCoroutine(AnimateImageFill(thisLevel_progressBar_Image, (float)targetTotalScore / Mathf.Max(1, _1000000), introBarFillDuration));
yield return StartCoroutine(FlashInTransform(finalLevel_img != null ? finalLevel_img.transform : null, 1, introStaticElementDuration));
yield return StartCoroutine(FlashInTransform(personalRecord_Text != null ? personalRecord_Text.transform : null, 1, introStaticElementDuration));
yield return StartCoroutine(FlashInTransform(gameNote_rate != null ? gameNote_rate.transform : null, 1, introStaticElementDuration));
// hitStatus/status groups: flash in and count up numbers
yield return StartCoroutine(PlayStatusGroupIn(perfectGroup, perfectHitCount_Text, targetPerfectCount, perfectHitPercent_Text, targetPerfectPercent));
yield return StartCoroutine(PlayStatusGroupIn(greatGroup, greatHitCount_Text, targetGreatCount, greatHitPercent_Text, targetGreatPercent));
yield return StartCoroutine(PlayStatusGroupIn(goodGroup, goodHitCount_Text, targetGoodCount, goodHitPercent_Text, targetGoodPercent));
yield return StartCoroutine(PlayStatusGroupIn(missGroup, missHitCount_Text, targetMissCount, missHitPercent_Text, targetMissPercent));
int noteCountForBars = Mathf.Max(1, targetPerfectCount + targetGreatCount + targetGoodCount + targetMissCount);
yield return StartCoroutine(PlayStatusGroupIn(perfectGroup, perfectHitCount_Text, targetPerfectCount, perfectHitPercent_Text, targetPerfectPercent, perfect_barFill_Image, (float)targetPerfectCount / noteCountForBars));
yield return StartCoroutine(PlayStatusGroupIn(greatGroup, greatHitCount_Text, targetGreatCount, greatHitPercent_Text, targetGreatPercent, great_barFill_Image, (float)targetGreatCount / noteCountForBars));
yield return StartCoroutine(PlayStatusGroupIn(goodGroup, goodHitCount_Text, targetGoodCount, goodHitPercent_Text, targetGoodPercent, good_barFill_Image, (float)targetGoodCount / noteCountForBars));
yield return StartCoroutine(PlayStatusGroupIn(missGroup, missHitCount_Text, targetMissCount, missHitPercent_Text, targetMissPercent, miss_barFill_Image, (float)targetMissCount / noteCountForBars));
yield return StartCoroutine(AnimateIntText(earlyHitCount_Text, targetEarlyCount, introNumberDuration * 0.7f));
yield return StartCoroutine(AnimateIntText(lateHitCount_Text, targetLateCount, introNumberDuration * 0.7f));
yield return StartCoroutine(AnimateOffsetText(avgOffset_Text, targetAvgOffsetMs, introNumberDuration * 0.7f));
// ally cards enter before MASK.
if (hasAllyCardEntry)
@@ -1247,6 +1331,7 @@ public class settlementController : MonoBehaviour
yield return WaitRealtime(introStepGap);
}
ApplySettlementIntroFinalState();
settlementCanvasGroup.alpha = 1f;
settlementCanvasGroup.interactable = true;
settlementCanvasGroup.blocksRaycasts = true;
@@ -1356,6 +1441,23 @@ public class settlementController : MonoBehaviour
if (good_barFill_Image != null) good_barFill_Image.fillAmount = (float)targetGoodCount / noteCountSum;
if (miss_barFill_Image != null) miss_barFill_Image.fillAmount = (float)targetMissCount / noteCountSum;
if (thisSong_backPic != null) SetCanvasAlpha(thisSong_backPic.transform, 1f);
if (songName_Text != null) SetCanvasAlpha(songName_Text.transform, 1f);
if (finalLevel_img != null) SetCanvasAlpha(finalLevel_img.transform, 1f);
if (personalRecord_Text != null)
{
if (!string.IsNullOrEmpty(targetPersonalRecordText)) personalRecord_Text.text = targetPersonalRecordText;
SetCanvasAlpha(personalRecord_Text.transform, 1f);
}
if (gameNote_rate != null)
{
if (!string.IsNullOrEmpty(targetGameNoteRateText)) gameNote_rate.text = targetGameNoteRateText;
SetCanvasAlpha(gameNote_rate.transform, 1f);
}
if (earlyHitCount_Text != null) { earlyHitCount_Text.text = targetEarlyCount.ToString(); SetCanvasAlpha(earlyHitCount_Text.transform, 1f); }
if (lateHitCount_Text != null) { lateHitCount_Text.text = targetLateCount.ToString(); SetCanvasAlpha(lateHitCount_Text.transform, 1f); }
if (avgOffset_Text != null) { avgOffset_Text.text = targetAvgOffsetMs.ToString("F2") + " ms"; SetCanvasAlpha(avgOffset_Text.transform, 1f); }
if (mvpTr != null && mvpTr.gameObject.activeInHierarchy)
{
Vector3 targetPos;
@@ -1585,16 +1687,23 @@ public class settlementController : MonoBehaviour
}
private IEnumerator PlayStatusGroupIn(Transform groupRoot, Text countText, int countTarget, Text percentText, float percentTarget)
{
yield return StartCoroutine(PlayStatusGroupIn(groupRoot, countText, countTarget, percentText, percentTarget, null, 0f));
}
private IEnumerator PlayStatusGroupIn(Transform groupRoot, Text countText, int countTarget, Text percentText, float percentTarget, Image fillImage, float fillTarget)
{
if (groupRoot != null)
yield return StartCoroutine(FlashInTransform(groupRoot, introFlashCount, introFlashDuration));
Coroutine c1 = null;
Coroutine c2 = null;
Coroutine c3 = null;
if (countText != null) c1 = StartCoroutine(AnimateIntText(countText, countTarget, introNumberDuration));
if (percentText != null) c2 = StartCoroutine(AnimateFloatPercentText(percentText, percentTarget, introNumberDuration, "F1"));
if (fillImage != null) c3 = StartCoroutine(AnimateImageFill(fillImage, fillTarget, introBarFillDuration));
if (c1 != null || c2 != null)
if (c1 != null || c2 != null || c3 != null)
yield return WaitRealtime(introNumberDuration + 0.02f);
}
@@ -1666,6 +1775,48 @@ public class settlementController : MonoBehaviour
target.text = toValue.ToString(format) + "%";
}
private IEnumerator AnimateOffsetText(Text target, float toValue, float duration)
{
if (target == null) yield break;
SetCanvasAlpha(target.transform, 1f);
float elapsed = 0f;
float dur = Mathf.Max(0.01f, duration);
while (elapsed < dur)
{
if (skipIntroRequested) break;
elapsed += Time.unscaledDeltaTime;
float t = EaseOutCubic(Mathf.Clamp01(elapsed / dur));
float value = Mathf.Lerp(0f, toValue, t);
target.text = value.ToString("F2") + " ms";
yield return null;
}
target.text = toValue.ToString("F2") + " ms";
}
private IEnumerator AnimateImageFill(Image target, float toValue, float duration)
{
if (target == null) yield break;
target.fillAmount = 0f;
float elapsed = 0f;
float dur = Mathf.Max(0.01f, duration);
float targetValue = Mathf.Clamp01(toValue);
while (elapsed < dur)
{
if (skipIntroRequested) break;
elapsed += Time.unscaledDeltaTime;
float t = EaseOutCubic(Mathf.Clamp01(elapsed / dur));
target.fillAmount = Mathf.Lerp(0f, targetValue, t);
yield return null;
}
target.fillAmount = targetValue;
}
private IEnumerator AnimateAnchoredXAndFade(RectTransform rt, float fromX, float toX, float duration, bool fadeIn)
{
if (rt == null) yield break;
@@ -1776,6 +1927,18 @@ public class settlementController : MonoBehaviour
SetCanvasAlpha(target, 1f);
}
private void PrepareStaticSettlementElement(Transform target)
{
if (target == null) return;
SetCanvasAlpha(target, 0f);
}
private void PrepareImageFill(Image target)
{
if (target == null) return;
target.fillAmount = 0f;
}
private void PrepareTextForCountUp(Text t, bool isPercent, float initialValue, string format = "F1")
{
if (t == null) return;