超大量的更新 修复很多问题,gameplay特效初步
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using DG.Tweening;
|
||||
|
||||
public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
public Image t_songCoverImage;
|
||||
public Image btm_songCoverImage;
|
||||
[Header("������Ϣ")]
|
||||
[Header("Inspector")]
|
||||
public Text songNameText;
|
||||
public Text currentDifficulty;
|
||||
public Text sumScore_thisDifficulty;
|
||||
@@ -18,26 +19,58 @@ public class selected_songInfo : MonoBehaviour
|
||||
|
||||
public Image c_DifficultyImage;
|
||||
public Image c_imageMask;
|
||||
[Header("�ּ���ɫ")]
|
||||
[Header("Inspector")]
|
||||
public Color _0to5d5;
|
||||
public Color _5d5to11;
|
||||
public Color _11to16d5;
|
||||
public Color _16d5to22;
|
||||
public Color _equal22;
|
||||
|
||||
[Header("��Ӧ���ѶȰ�ť")]
|
||||
[Header("Inspector")]
|
||||
public List<Button> difficultyButtons = new List<Button>();
|
||||
[Header("��Ӧ���Ѷ��ı�")]
|
||||
[Header("Inspector")]
|
||||
public List<Text> difficultyTexts = new List<Text>();
|
||||
[Header("enter detail page")]
|
||||
public Button enterDetailPageButton;
|
||||
[Header("quick enter game play")]
|
||||
public Button quickEnter_gamePlay;
|
||||
[Header("ָ��image����ɫ")]
|
||||
[Header("Inspector")]
|
||||
public Sprite buttons_bgImage;
|
||||
[Header("black mask")]
|
||||
public Image blackMaskImage;
|
||||
|
||||
[Header("Quick Enter Prompt UI")]
|
||||
[SerializeField] GameObject mustSelectYourIdolRoot;
|
||||
[SerializeField] GameObject noChoiceRoot;
|
||||
[SerializeField] GameObject choiceLessThanFiveRoot;
|
||||
[SerializeField] Button promptContinueButton;
|
||||
[SerializeField] Button promptConsiderButton;
|
||||
[SerializeField] Button promptDoNotShowAgainButton;
|
||||
[SerializeField] Button promptOkayButton;
|
||||
[SerializeField] float promptFlashOnTime = 0.04f;
|
||||
[SerializeField] float promptFlashOffTime = 0.03f;
|
||||
[SerializeField] int promptFlashCount = 2;
|
||||
[SerializeField] Color doNotShowOffButtonColor = Color.white;
|
||||
[SerializeField] Color doNotShowOnButtonColor = new Color(0.227f, 0.227f, 0.227f, 1f);
|
||||
[SerializeField] Color doNotShowOffTextColor = new Color(0.227f, 0.227f, 0.227f, 1f);
|
||||
[SerializeField] Color doNotShowOnTextColor = Color.white;
|
||||
|
||||
private Coroutine _quickEnterPromptRoutine;
|
||||
private bool _promptAwaitingChoice = false;
|
||||
private bool _doNotShowAgainPrompt = false;
|
||||
private bool _doNotShowPrefLoaded = false;
|
||||
|
||||
private const string QuickEnterPromptSkipPrefKey = "quickenter_team_warning_skip";
|
||||
|
||||
private enum QuickEnterPromptDecision
|
||||
{
|
||||
None = 0,
|
||||
Continue = 1,
|
||||
Consider = 2
|
||||
}
|
||||
|
||||
private QuickEnterPromptDecision _promptDecision = QuickEnterPromptDecision.None;
|
||||
|
||||
// store the original sprites so we don't overwrite the designer's setup
|
||||
private List<Sprite> originalButtonSprites = new List<Sprite>();
|
||||
|
||||
@@ -58,11 +91,133 @@ public class selected_songInfo : MonoBehaviour
|
||||
private bool songInfo_BaseCached;
|
||||
private int lastSongId = -1;
|
||||
|
||||
[Header("Difficulty ID Roll")]
|
||||
[SerializeField] string difficultyIdName = "difficultyID";
|
||||
[SerializeField] string difficultyIdGroundName = "difficultyIDGround";
|
||||
[SerializeField] float difficultyIdStepDelayFast = 0.03f;
|
||||
[SerializeField] float difficultyIdStepDelaySlow = 0.11f;
|
||||
[SerializeField] bool difficultyIdUseUnscaledTime = true;
|
||||
|
||||
private readonly List<Text> difficultyIdDisplayTexts = new List<Text>();
|
||||
private Coroutine difficultyIdRollCoroutine;
|
||||
private int difficultyIdDisplayed = int.MinValue;
|
||||
|
||||
private static void LogVerbose(string message)
|
||||
{
|
||||
if (GameConfig.verboseLogs) Debug.LogWarning(message);
|
||||
}
|
||||
|
||||
private void ResolveDifficultyIdDisplayTexts()
|
||||
{
|
||||
difficultyIdDisplayTexts.Clear();
|
||||
|
||||
Text[] allTexts = Resources.FindObjectsOfTypeAll<Text>();
|
||||
for (int i = 0; i < allTexts.Length; i++)
|
||||
{
|
||||
Text txt = allTexts[i];
|
||||
if (txt == null) continue;
|
||||
if (txt.gameObject == null || txt.gameObject.scene != gameObject.scene) continue;
|
||||
|
||||
bool nameMatch = string.Equals(txt.name, difficultyIdName, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(txt.name, difficultyIdGroundName, StringComparison.OrdinalIgnoreCase);
|
||||
if (!nameMatch) continue;
|
||||
|
||||
txt.raycastTarget = false;
|
||||
difficultyIdDisplayTexts.Add(txt);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyDifficultyIdDisplayValue(int value)
|
||||
{
|
||||
if (difficultyIdDisplayTexts.Count == 0)
|
||||
ResolveDifficultyIdDisplayTexts();
|
||||
|
||||
string text = value.ToString();
|
||||
for (int i = 0; i < difficultyIdDisplayTexts.Count; i++)
|
||||
{
|
||||
Text t = difficultyIdDisplayTexts[i];
|
||||
if (t == null) continue;
|
||||
t.text = text;
|
||||
t.raycastTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDifficultyIdDisplayAnimated(float difficultyLevel, bool instant)
|
||||
{
|
||||
int target = Mathf.RoundToInt(difficultyLevel);
|
||||
if (target < 0) target = 0;
|
||||
|
||||
if (instant || difficultyIdDisplayed == int.MinValue)
|
||||
{
|
||||
difficultyIdDisplayed = target;
|
||||
ApplyDifficultyIdDisplayValue(target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (target == difficultyIdDisplayed)
|
||||
{
|
||||
ApplyDifficultyIdDisplayValue(target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (difficultyIdRollCoroutine != null)
|
||||
{
|
||||
StopCoroutine(difficultyIdRollCoroutine);
|
||||
difficultyIdRollCoroutine = null;
|
||||
}
|
||||
difficultyIdRollCoroutine = StartCoroutine(RollDifficultyIdDisplay(difficultyIdDisplayed, target));
|
||||
}
|
||||
|
||||
private IEnumerator RollDifficultyIdDisplay(int from, int target)
|
||||
{
|
||||
int distance = Mathf.Abs(target - from);
|
||||
if (distance == 0)
|
||||
{
|
||||
ApplyDifficultyIdDisplayValue(target);
|
||||
difficultyIdDisplayed = target;
|
||||
difficultyIdRollCoroutine = null;
|
||||
yield break;
|
||||
}
|
||||
|
||||
int dir = target > from ? 1 : -1;
|
||||
int current = from;
|
||||
for (int i = 1; i <= distance; i++)
|
||||
{
|
||||
current += dir;
|
||||
difficultyIdDisplayed = current;
|
||||
ApplyDifficultyIdDisplayValue(current);
|
||||
|
||||
float progress = distance <= 1 ? 1f : (float)i / distance;
|
||||
float eased = progress * progress; // fast at start, slower near final value
|
||||
float delay = Mathf.Lerp(difficultyIdStepDelayFast, difficultyIdStepDelaySlow, eased);
|
||||
if (difficultyIdUseUnscaledTime)
|
||||
yield return new WaitForSecondsRealtime(Mathf.Max(0.005f, delay));
|
||||
else
|
||||
yield return new WaitForSeconds(Mathf.Max(0.005f, delay));
|
||||
}
|
||||
|
||||
difficultyIdDisplayed = target;
|
||||
ApplyDifficultyIdDisplayValue(target);
|
||||
difficultyIdRollCoroutine = null;
|
||||
}
|
||||
|
||||
private int GetTeamMemberCount()
|
||||
{
|
||||
int id1 = PlayerPrefs.GetInt("selected_heroSlot01_heroID", 0);
|
||||
int id2 = PlayerPrefs.GetInt("selected_heroSlot02_heroID", 0);
|
||||
int id3 = PlayerPrefs.GetInt("selected_heroSlot03_heroID", 0);
|
||||
int id4 = PlayerPrefs.GetInt("selected_heroSlot04_heroID", 0);
|
||||
int id5 = PlayerPrefs.GetInt("selected_heroSlot05_heroID", 0);
|
||||
|
||||
int count = 0;
|
||||
if (id1 != 0) count++;
|
||||
if (id2 != 0) count++;
|
||||
if (id3 != 0) count++;
|
||||
if (id4 != 0) count++;
|
||||
if (id5 != 0) count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
LogVerbose("selected_songInfo.Awake called");
|
||||
@@ -71,6 +226,12 @@ public class selected_songInfo : MonoBehaviour
|
||||
void OnEnable()
|
||||
{
|
||||
LogVerbose("selected_songInfo.OnEnable called");
|
||||
EnsurePromptReferences();
|
||||
LoadDoNotShowAgainPreference();
|
||||
SetPromptRootVisible(false);
|
||||
ApplyDoNotShowAgainVisual();
|
||||
ResolveDifficultyIdDisplayTexts();
|
||||
|
||||
// register listeners here to ensure binding even if Start wasn't called yet
|
||||
if (enterDetailPageButton != null)
|
||||
{
|
||||
@@ -93,6 +254,8 @@ public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
LogVerbose("quickEnter_gamePlay is null in OnEnable");
|
||||
}
|
||||
|
||||
BindPromptButtons();
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
@@ -106,6 +269,20 @@ public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
quickEnter_gamePlay.onClick.RemoveListener(OnQuickEnterClicked);
|
||||
}
|
||||
|
||||
UnbindPromptButtons();
|
||||
_promptAwaitingChoice = false;
|
||||
_promptDecision = QuickEnterPromptDecision.None;
|
||||
if (_quickEnterPromptRoutine != null)
|
||||
{
|
||||
StopCoroutine(_quickEnterPromptRoutine);
|
||||
_quickEnterPromptRoutine = null;
|
||||
}
|
||||
if (difficultyIdRollCoroutine != null)
|
||||
{
|
||||
StopCoroutine(difficultyIdRollCoroutine);
|
||||
difficultyIdRollCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
@@ -119,6 +296,12 @@ public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
LogVerbose("selected_songInfo.Start called");
|
||||
|
||||
EnsurePromptReferences();
|
||||
LoadDoNotShowAgainPreference();
|
||||
SetPromptRootVisible(false);
|
||||
ApplyDoNotShowAgainVisual();
|
||||
ResolveDifficultyIdDisplayTexts();
|
||||
|
||||
// ensure black mask is transparent and inactive at start
|
||||
if (blackMaskImage != null)
|
||||
{
|
||||
@@ -201,6 +384,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
currentDifficulty.text = difficultyLevel.ToString("0.0");
|
||||
}
|
||||
UpdateDifficultyIdDisplayAnimated(difficultyLevel, false);
|
||||
|
||||
if (c_DifficultyImage != null)
|
||||
{
|
||||
@@ -311,7 +495,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
}
|
||||
if (songNameText != null)
|
||||
{
|
||||
songNameText.text = "δѡ�����";
|
||||
songNameText.text = "未选择歌曲";
|
||||
}
|
||||
|
||||
// restore original difficulty button backgrounds and text colors
|
||||
@@ -319,6 +503,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
|
||||
if (sumScore_thisDifficulty != null) sumScore_thisDifficulty.text = "0";
|
||||
if (total_gameTime != null) total_gameTime.text = "0";
|
||||
UpdateDifficultyIdDisplayAnimated(0f, true);
|
||||
lastSongId = -1;
|
||||
}
|
||||
}
|
||||
@@ -505,7 +690,255 @@ public class selected_songInfo : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadDoNotShowAgainPreference()
|
||||
{
|
||||
if (_doNotShowPrefLoaded) return;
|
||||
_doNotShowAgainPrompt = PlayerPrefs.GetInt(QuickEnterPromptSkipPrefKey, 0) == 1;
|
||||
_doNotShowPrefLoaded = true;
|
||||
}
|
||||
|
||||
private void SetDoNotShowAgainPreference(bool enabled)
|
||||
{
|
||||
_doNotShowAgainPrompt = enabled;
|
||||
_doNotShowPrefLoaded = true;
|
||||
PlayerPrefs.SetInt(QuickEnterPromptSkipPrefKey, enabled ? 1 : 0);
|
||||
PlayerPrefs.Save();
|
||||
ApplyDoNotShowAgainVisual();
|
||||
}
|
||||
|
||||
private void EnsurePromptReferences()
|
||||
{
|
||||
if (mustSelectYourIdolRoot == null)
|
||||
{
|
||||
mustSelectYourIdolRoot = FindSceneObjectByExactName("\uFF01mustselectyouridol");
|
||||
if (mustSelectYourIdolRoot == null)
|
||||
mustSelectYourIdolRoot = FindSceneObjectByContainsName("mustselectyouridol");
|
||||
}
|
||||
|
||||
if (mustSelectYourIdolRoot != null)
|
||||
{
|
||||
if (noChoiceRoot == null)
|
||||
noChoiceRoot = FindChildByName(mustSelectYourIdolRoot.transform, "No choice");
|
||||
if (choiceLessThanFiveRoot == null)
|
||||
choiceLessThanFiveRoot = FindChildByName(mustSelectYourIdolRoot.transform, "choice < 5");
|
||||
if (promptContinueButton == null)
|
||||
promptContinueButton = FindButtonByName(mustSelectYourIdolRoot.transform, "Continue");
|
||||
if (promptConsiderButton == null)
|
||||
promptConsiderButton = FindButtonByName(mustSelectYourIdolRoot.transform, "Consider");
|
||||
if (promptDoNotShowAgainButton == null)
|
||||
promptDoNotShowAgainButton = FindButtonByName(mustSelectYourIdolRoot.transform, "Do not show again");
|
||||
if (promptOkayButton == null)
|
||||
promptOkayButton = FindButtonByName(mustSelectYourIdolRoot.transform, "okay");
|
||||
}
|
||||
}
|
||||
|
||||
private void BindPromptButtons()
|
||||
{
|
||||
EnsurePromptReferences();
|
||||
|
||||
if (promptContinueButton != null)
|
||||
{
|
||||
promptContinueButton.onClick.RemoveListener(OnPromptContinueClicked);
|
||||
promptContinueButton.onClick.AddListener(OnPromptContinueClicked);
|
||||
}
|
||||
|
||||
if (promptConsiderButton != null)
|
||||
{
|
||||
promptConsiderButton.onClick.RemoveListener(OnPromptConsiderClicked);
|
||||
promptConsiderButton.onClick.AddListener(OnPromptConsiderClicked);
|
||||
}
|
||||
|
||||
if (promptDoNotShowAgainButton != null)
|
||||
{
|
||||
promptDoNotShowAgainButton.onClick.RemoveListener(OnPromptDoNotShowAgainClicked);
|
||||
promptDoNotShowAgainButton.onClick.AddListener(OnPromptDoNotShowAgainClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnbindPromptButtons()
|
||||
{
|
||||
if (promptContinueButton != null)
|
||||
promptContinueButton.onClick.RemoveListener(OnPromptContinueClicked);
|
||||
if (promptConsiderButton != null)
|
||||
promptConsiderButton.onClick.RemoveListener(OnPromptConsiderClicked);
|
||||
if (promptDoNotShowAgainButton != null)
|
||||
promptDoNotShowAgainButton.onClick.RemoveListener(OnPromptDoNotShowAgainClicked);
|
||||
}
|
||||
|
||||
private void OnPromptContinueClicked()
|
||||
{
|
||||
if (!_promptAwaitingChoice) return;
|
||||
_promptDecision = QuickEnterPromptDecision.Continue;
|
||||
}
|
||||
|
||||
private void OnPromptConsiderClicked()
|
||||
{
|
||||
if (!_promptAwaitingChoice) return;
|
||||
_promptDecision = QuickEnterPromptDecision.Consider;
|
||||
}
|
||||
|
||||
private void OnPromptDoNotShowAgainClicked()
|
||||
{
|
||||
LoadDoNotShowAgainPreference();
|
||||
SetDoNotShowAgainPreference(!_doNotShowAgainPrompt);
|
||||
}
|
||||
|
||||
private void ApplyDoNotShowAgainVisual()
|
||||
{
|
||||
if (promptDoNotShowAgainButton == null) return;
|
||||
|
||||
Graphic g = promptDoNotShowAgainButton.targetGraphic;
|
||||
if (g != null)
|
||||
{
|
||||
g.color = _doNotShowAgainPrompt ? doNotShowOnButtonColor : doNotShowOffButtonColor;
|
||||
}
|
||||
|
||||
Text[] texts = promptDoNotShowAgainButton.GetComponentsInChildren<Text>(true);
|
||||
Color textColor = _doNotShowAgainPrompt ? doNotShowOnTextColor : doNotShowOffTextColor;
|
||||
for (int i = 0; i < texts.Length; i++)
|
||||
{
|
||||
if (texts[i] != null)
|
||||
texts[i].color = textColor;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPromptRootVisible(bool visible)
|
||||
{
|
||||
if (mustSelectYourIdolRoot == null) return;
|
||||
mustSelectYourIdolRoot.SetActive(visible);
|
||||
if (!visible)
|
||||
{
|
||||
SetPromptCaseState(showNoChoice: false, showChoiceLessThanFive: false);
|
||||
SetPromptButtonsVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPromptCaseState(bool showNoChoice, bool showChoiceLessThanFive)
|
||||
{
|
||||
if (noChoiceRoot != null) noChoiceRoot.SetActive(showNoChoice);
|
||||
if (choiceLessThanFiveRoot != null) choiceLessThanFiveRoot.SetActive(showChoiceLessThanFive);
|
||||
}
|
||||
|
||||
private void SetPromptButtonsVisible(bool visible)
|
||||
{
|
||||
if (promptContinueButton != null) promptContinueButton.gameObject.SetActive(visible);
|
||||
if (promptConsiderButton != null) promptConsiderButton.gameObject.SetActive(visible);
|
||||
if (promptDoNotShowAgainButton != null) promptDoNotShowAgainButton.gameObject.SetActive(visible);
|
||||
if (promptOkayButton != null) promptOkayButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private IEnumerator FlashShowObject(GameObject go)
|
||||
{
|
||||
if (go == null) yield break;
|
||||
|
||||
go.SetActive(true);
|
||||
|
||||
CanvasGroup cg = go.GetComponent<CanvasGroup>();
|
||||
if (cg == null) cg = go.AddComponent<CanvasGroup>();
|
||||
|
||||
int flashes = Mathf.Max(1, promptFlashCount);
|
||||
// Force high-speed flashing even if inspector values are larger.
|
||||
float onTime = Mathf.Clamp(promptFlashOnTime, 0.01f, 0.05f);
|
||||
float offTime = Mathf.Clamp(promptFlashOffTime, 0.01f, 0.04f);
|
||||
|
||||
cg.alpha = 0f;
|
||||
for (int i = 0; i < flashes; i++)
|
||||
{
|
||||
cg.alpha = 1f;
|
||||
yield return new WaitForSecondsRealtime(onTime);
|
||||
if (i < flashes - 1)
|
||||
{
|
||||
cg.alpha = 0f;
|
||||
yield return new WaitForSecondsRealtime(offTime);
|
||||
}
|
||||
}
|
||||
cg.alpha = 1f;
|
||||
}
|
||||
|
||||
private GameObject FindSceneObjectByExactName(string objectName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(objectName)) return null;
|
||||
Transform[] all = Resources.FindObjectsOfTypeAll<Transform>();
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
Transform t = all[i];
|
||||
if (t == null || !t.gameObject.scene.IsValid()) continue;
|
||||
if (string.Equals(t.name, objectName, StringComparison.OrdinalIgnoreCase))
|
||||
return t.gameObject;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private GameObject FindSceneObjectByContainsName(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token)) return null;
|
||||
Transform[] all = Resources.FindObjectsOfTypeAll<Transform>();
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
Transform t = all[i];
|
||||
if (t == null || !t.gameObject.scene.IsValid()) continue;
|
||||
if (t.name.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
return t.gameObject;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private GameObject FindChildByName(Transform root, string childName)
|
||||
{
|
||||
if (root == null || string.IsNullOrEmpty(childName)) return null;
|
||||
|
||||
// Prefer direct children first.
|
||||
for (int i = 0; i < root.childCount; i++)
|
||||
{
|
||||
Transform c = root.GetChild(i);
|
||||
if (c != null && string.Equals(c.name, childName, StringComparison.OrdinalIgnoreCase))
|
||||
return c.gameObject;
|
||||
}
|
||||
|
||||
// Fallback: any descendant.
|
||||
Transform[] all = root.GetComponentsInChildren<Transform>(true);
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
Transform c = all[i];
|
||||
if (c != null && string.Equals(c.name, childName, StringComparison.OrdinalIgnoreCase))
|
||||
return c.gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Button FindButtonByName(Transform root, string buttonName)
|
||||
{
|
||||
if (root == null || string.IsNullOrEmpty(buttonName)) return null;
|
||||
Button[] btns = root.GetComponentsInChildren<Button>(true);
|
||||
for (int i = 0; i < btns.Length; i++)
|
||||
{
|
||||
Button b = btns[i];
|
||||
if (b != null && string.Equals(b.gameObject.name, buttonName, StringComparison.OrdinalIgnoreCase))
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnQuickEnterClicked()
|
||||
{
|
||||
int teamCount = GetTeamMemberCount();
|
||||
bool needTeamWarning = teamCount < 5;
|
||||
|
||||
if (needTeamWarning)
|
||||
{
|
||||
LoadDoNotShowAgainPreference();
|
||||
if (!_doNotShowAgainPrompt)
|
||||
{
|
||||
ShowQuickEnterPromptForTeam(teamCount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BeginQuickEnterInternal();
|
||||
}
|
||||
|
||||
private void BeginQuickEnterInternal()
|
||||
{
|
||||
// use SongData from holder or SongButton; ensure selection exists
|
||||
SongData sd = FindSongDataFromSelectedButton();
|
||||
@@ -538,6 +971,72 @@ public class selected_songInfo : MonoBehaviour
|
||||
StartCoroutine(QuickEnterSequence());
|
||||
}
|
||||
|
||||
private void ShowQuickEnterPromptForTeam(int teamCount)
|
||||
{
|
||||
EnsurePromptReferences();
|
||||
LoadDoNotShowAgainPreference();
|
||||
ApplyDoNotShowAgainVisual();
|
||||
|
||||
if (mustSelectYourIdolRoot == null)
|
||||
{
|
||||
// If UI is missing, fallback to direct quick enter to avoid dead-end.
|
||||
BeginQuickEnterInternal();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_quickEnterPromptRoutine != null)
|
||||
{
|
||||
StopCoroutine(_quickEnterPromptRoutine);
|
||||
_quickEnterPromptRoutine = null;
|
||||
}
|
||||
|
||||
_quickEnterPromptRoutine = StartCoroutine(QuickEnterPromptRoutine(teamCount));
|
||||
}
|
||||
|
||||
private IEnumerator QuickEnterPromptRoutine(int teamCount)
|
||||
{
|
||||
_promptAwaitingChoice = false;
|
||||
_promptDecision = QuickEnterPromptDecision.None;
|
||||
|
||||
SetPromptRootVisible(true);
|
||||
SetPromptCaseState(showNoChoice: false, showChoiceLessThanFive: false);
|
||||
SetPromptButtonsVisible(false);
|
||||
ApplyDoNotShowAgainVisual();
|
||||
|
||||
yield return FlashShowObject(mustSelectYourIdolRoot);
|
||||
|
||||
bool isTeamEmpty = teamCount <= 0;
|
||||
if (isTeamEmpty)
|
||||
{
|
||||
SetPromptCaseState(showNoChoice: true, showChoiceLessThanFive: false);
|
||||
yield return FlashShowObject(noChoiceRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPromptCaseState(showNoChoice: false, showChoiceLessThanFive: true);
|
||||
yield return FlashShowObject(choiceLessThanFiveRoot);
|
||||
}
|
||||
|
||||
// Buttons are displayed directly without flashing.
|
||||
SetPromptButtonsVisible(true);
|
||||
|
||||
_promptAwaitingChoice = true;
|
||||
while (_promptDecision == QuickEnterPromptDecision.None)
|
||||
yield return null;
|
||||
|
||||
_promptAwaitingChoice = false;
|
||||
QuickEnterPromptDecision decision = _promptDecision;
|
||||
_promptDecision = QuickEnterPromptDecision.None;
|
||||
SetPromptRootVisible(false);
|
||||
|
||||
_quickEnterPromptRoutine = null;
|
||||
|
||||
if (decision == QuickEnterPromptDecision.Continue)
|
||||
{
|
||||
BeginQuickEnterInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator QuickEnterSequence()
|
||||
{
|
||||
LogVerbose("QuickEnterSequence started: beginning fade");
|
||||
@@ -598,7 +1097,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
|
||||
private SongData FindSongDataFromSelectedButton()
|
||||
{
|
||||
var allButtons = Object.FindObjectsByType<SongButton>(FindObjectsInactive.Exclude, FindObjectsSortMode.InstanceID);
|
||||
var allButtons = UnityEngine.Object.FindObjectsByType<SongButton>(FindObjectsInactive.Exclude, FindObjectsSortMode.InstanceID);
|
||||
LogVerbose($"FindSongDataFromSelectedButton: found {allButtons.Length} SongButton instances");
|
||||
foreach (var sb in allButtons)
|
||||
{
|
||||
@@ -694,8 +1193,8 @@ public class selected_songInfo : MonoBehaviour
|
||||
}
|
||||
|
||||
// find managers in the new scene
|
||||
var beatmapManager = Object.FindAnyObjectByType<BeatmapManager>();
|
||||
var gameManager = Object.FindAnyObjectByType<GameManager>();
|
||||
var beatmapManager = UnityEngine.Object.FindAnyObjectByType<BeatmapManager>();
|
||||
var gameManager = UnityEngine.Object.FindAnyObjectByType<GameManager>();
|
||||
|
||||
LogVerbose($"selected song: {selected.songName} (id {selected.songID}), difficulty {selected.thisLevel_selectedDifficultyID}");
|
||||
|
||||
@@ -809,7 +1308,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
|
||||
// Start coroutine to wait for player input (Space) to begin playback and spawning
|
||||
// Use a safe host for coroutine in case this MonoBehaviour is destroyed unexpectedly
|
||||
var pauseMgr = PauseManager.Instance != null ? PauseManager.Instance : Object.FindAnyObjectByType<PauseManager>();
|
||||
var pauseMgr = PauseManager.Instance != null ? PauseManager.Instance : UnityEngine.Object.FindAnyObjectByType<PauseManager>();
|
||||
MonoBehaviour coroutineHost = (pauseMgr as MonoBehaviour) ?? (gameManager as MonoBehaviour) ?? (beatmapManager as MonoBehaviour) ?? this;
|
||||
if (coroutineHost != null)
|
||||
{
|
||||
@@ -859,7 +1358,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
}
|
||||
|
||||
// Prewarm particle systems via AnimationController to avoid first-play hitch
|
||||
var anim = AnimationController.Global != null ? AnimationController.Global : Object.FindAnyObjectByType<AnimationController>();
|
||||
var anim = AnimationController.Global != null ? AnimationController.Global : UnityEngine.Object.FindAnyObjectByType<AnimationController>();
|
||||
if (anim != null)
|
||||
{
|
||||
LogVerbose("Starting AnimationController particle prewarm (will wait until complete)...");
|
||||
@@ -869,7 +1368,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
}
|
||||
|
||||
// Unpause via PauseManager
|
||||
var pauseMgr = PauseManager.Instance != null ? PauseManager.Instance : Object.FindAnyObjectByType<PauseManager>();
|
||||
var pauseMgr = PauseManager.Instance != null ? PauseManager.Instance : UnityEngine.Object.FindAnyObjectByType<PauseManager>();
|
||||
if (pauseMgr != null) pauseMgr.Pause(false);
|
||||
|
||||
// small buffer to avoid hitching immediately after unpause: wait configured delay from GameManager
|
||||
@@ -929,7 +1428,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
Debug.LogWarning($"enterDetailPageButton assigned={(enterDetailPageButton==null?"NULL":"ASSIGNED")}");
|
||||
Debug.LogWarning($"blackMaskImage assigned={(blackMaskImage==null?"NULL":"ASSIGNED")}");
|
||||
Debug.LogWarning($"SongDataHolder.SelectedSongData={(SongDataHolder.SelectedSongData==null?"NULL":SongDataHolder.SelectedSongData.songName)}");
|
||||
var allButtons = Object.FindObjectsByType<SongButton>(FindObjectsInactive.Exclude, FindObjectsSortMode.InstanceID);
|
||||
var allButtons = UnityEngine.Object.FindObjectsByType<SongButton>(FindObjectsInactive.Exclude, FindObjectsSortMode.InstanceID);
|
||||
Debug.LogWarning($"Found {allButtons.Length} SongButton instances in scene");
|
||||
for (int i = 0; i < allButtons.Length; i++)
|
||||
{
|
||||
@@ -945,7 +1444,7 @@ public class selected_songInfo : MonoBehaviour
|
||||
private void RequestPauseManagerPause()
|
||||
{
|
||||
if (pauseRequested) return;
|
||||
var pm = PauseManager.Instance != null ? PauseManager.Instance : Object.FindAnyObjectByType<PauseManager>();
|
||||
var pm = PauseManager.Instance != null ? PauseManager.Instance : UnityEngine.Object.FindAnyObjectByType<PauseManager>();
|
||||
if (pm != null)
|
||||
{
|
||||
pm.Pause(true);
|
||||
|
||||
Reference in New Issue
Block a user