长音符再修复 加入了关卡连接 优化了一些默认加载
This commit is contained in:
@@ -11,6 +11,7 @@ public class dlcButton : MonoBehaviour
|
||||
public Text dlcID;
|
||||
public Text dlcProducer;
|
||||
public Text dlcPubliushDate;
|
||||
public Image dlc_nowSelectedImageBoarder;
|
||||
[Header("介绍")]
|
||||
public Text dlcDescription;
|
||||
|
||||
@@ -26,6 +27,14 @@ public class dlcButton : MonoBehaviour
|
||||
|
||||
private Button _btn;
|
||||
|
||||
// Selection management (shared across all dlcButton instances)
|
||||
private static List<dlcButton> allButtons = new List<dlcButton>();
|
||||
private static int selectedIndex = -1;
|
||||
private const string PlayerPrefsKey = "dlc_selected_index";
|
||||
|
||||
// instance index in registration order
|
||||
private int instanceIndex = -1;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_btn = GetComponent<Button>();
|
||||
@@ -34,49 +43,141 @@ public class dlcButton : MonoBehaviour
|
||||
_btn.onClick.RemoveAllListeners();
|
||||
_btn.onClick.AddListener(OnButtonClicked_ShowSongs);
|
||||
}
|
||||
|
||||
// register this button for centralized selection handling
|
||||
RegisterInstance();
|
||||
|
||||
// ensure border initial state
|
||||
if (dlc_nowSelectedImageBoarder != null)
|
||||
{
|
||||
var c = dlc_nowSelectedImageBoarder.color;
|
||||
c.a = 0f;
|
||||
dlc_nowSelectedImageBoarder.color = c;
|
||||
dlc_nowSelectedImageBoarder.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
Debug.Log($"dlcButton.Awake: registered '{gameObject.name}' as index {instanceIndex}");
|
||||
}
|
||||
|
||||
// Resolve dlcData after all buttons have been instantiated
|
||||
public void ResolveDlcData()
|
||||
private void RegisterInstance()
|
||||
{
|
||||
Debug.Log($"dlcButton.ResolveDlcData called on '{gameObject.name}'");
|
||||
|
||||
if (dlcDataSO != null)
|
||||
if (!allButtons.Contains(this))
|
||||
{
|
||||
Debug.Log($"dlcButton: dlcDataSO already assigned on '{gameObject.name}' -> {dlcDataSO.name}");
|
||||
ApplyDlcData(dlcDataSO);
|
||||
return;
|
||||
}
|
||||
instanceIndex = allButtons.Count;
|
||||
allButtons.Add(this);
|
||||
|
||||
int id = 0;
|
||||
if (dlcID != null && int.TryParse(dlcID.text, out id))
|
||||
{
|
||||
Debug.Log($"dlcButton: Resolving by dlcID text {id} for '{gameObject.name}'");
|
||||
LoadDlcDataById(id);
|
||||
return;
|
||||
}
|
||||
|
||||
string goName = gameObject.name;
|
||||
if (!string.IsNullOrEmpty(goName))
|
||||
{
|
||||
var parts = goName.Split('_');
|
||||
int parsed = 0;
|
||||
if (parts.Length > 0 && int.TryParse(parts[0], out parsed))
|
||||
// If no selectedIndex loaded yet, load from PlayerPrefs default 0
|
||||
if (selectedIndex == -1)
|
||||
{
|
||||
Debug.Log($"dlcButton: Resolving by GameObject name prefix {parsed} for '{gameObject.name}'");
|
||||
LoadDlcDataById(parsed);
|
||||
selectedIndex = PlayerPrefs.GetInt(PlayerPrefsKey, 0);
|
||||
}
|
||||
|
||||
// If this instance matches the persisted selection, apply selection
|
||||
if (instanceIndex == selectedIndex)
|
||||
{
|
||||
// ensure other buttons are deselected
|
||||
ApplySelectionToAll(instanceIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.ResolveDlcData: could not parse id from GameObject name '{goName}'");
|
||||
// ensure unselected visual
|
||||
SetSelectedVisual(false, immediate: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UnregisterInstance()
|
||||
{
|
||||
if (allButtons.Contains(this))
|
||||
{
|
||||
int idx = allButtons.IndexOf(this);
|
||||
allButtons.Remove(this);
|
||||
|
||||
// if removed index was before selectedIndex, adjust saved index
|
||||
if (idx >= 0 && idx < instanceIndex)
|
||||
{
|
||||
// nothing: instanceIndex only used at registration time
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
UnregisterInstance();
|
||||
}
|
||||
|
||||
// Ensure only one button is selected and persist the index
|
||||
public void Select()
|
||||
{
|
||||
ApplySelectionToAll(instanceIndex);
|
||||
selectedIndex = instanceIndex;
|
||||
PlayerPrefs.SetInt(PlayerPrefsKey, selectedIndex);
|
||||
PlayerPrefs.Save();
|
||||
Debug.Log($"dlcButton.Select: '{gameObject.name}' selected (index {instanceIndex}) and saved to PlayerPrefs");
|
||||
}
|
||||
|
||||
private static void ApplySelectionToAll(int selectIdx)
|
||||
{
|
||||
for (int i = 0; i < allButtons.Count; i++)
|
||||
{
|
||||
var btn = allButtons[i];
|
||||
if (btn == null) continue;
|
||||
bool shouldSelect = (i == selectIdx);
|
||||
btn.SetSelectedVisual(shouldSelect);
|
||||
}
|
||||
}
|
||||
|
||||
// fades the border in or out; if immediate, set without coroutine
|
||||
private Coroutine borderFadeCoroutine = null;
|
||||
private void SetSelectedVisual(bool selected, bool immediate = false)
|
||||
{
|
||||
if (dlc_nowSelectedImageBoarder == null) return;
|
||||
|
||||
if (borderFadeCoroutine != null)
|
||||
{
|
||||
StopCoroutine(borderFadeCoroutine);
|
||||
borderFadeCoroutine = null;
|
||||
}
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
dlc_nowSelectedImageBoarder.gameObject.SetActive(selected);
|
||||
var c = dlc_nowSelectedImageBoarder.color;
|
||||
c.a = selected ? 1f : 0f;
|
||||
dlc_nowSelectedImageBoarder.color = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.ResolveDlcData: no dlcID text and no name to parse for '{gameObject.name}'");
|
||||
dlc_nowSelectedImageBoarder.gameObject.SetActive(true);
|
||||
borderFadeCoroutine = StartCoroutine(FadeBorder(dlc_nowSelectedImageBoarder, selected ? 1f : 0f, 0.25f));
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator<YieldInstruction> FadeBorder(Image img, float targetAlpha, float duration)
|
||||
{
|
||||
if (img == null) yield break;
|
||||
float startAlpha = img.color.a;
|
||||
float t = 0f;
|
||||
// if fading out, ensure we start from current alpha
|
||||
while (t < duration)
|
||||
{
|
||||
t += Time.unscaledDeltaTime;
|
||||
float a = Mathf.Lerp(startAlpha, targetAlpha, Mathf.Clamp01(t / duration));
|
||||
var c = img.color;
|
||||
c.a = a;
|
||||
img.color = c;
|
||||
yield return null;
|
||||
}
|
||||
var final = img.color;
|
||||
final.a = targetAlpha;
|
||||
img.color = final;
|
||||
if (Mathf.Approximately(targetAlpha, 0f))
|
||||
{
|
||||
img.gameObject.SetActive(false);
|
||||
}
|
||||
borderFadeCoroutine = null;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Do not auto-resolve here anymore. Resolution will be triggered externally after instantiation of all buttons.
|
||||
@@ -84,6 +185,27 @@ public class dlcButton : MonoBehaviour
|
||||
|
||||
public void OnButtonClicked_ShowSongs()
|
||||
{
|
||||
// set current DLC key for SongSelectUI to allow per-DLC song selection restore
|
||||
string dlcKey = null;
|
||||
if (dlcDataSO != null)
|
||||
{
|
||||
dlcKey = "dlc_" + dlcDataSO.dlcID;
|
||||
}
|
||||
else if (dlcID != null && int.TryParse(dlcID.text, out int parsedId))
|
||||
{
|
||||
dlcKey = "dlc_" + parsedId;
|
||||
}
|
||||
else
|
||||
{
|
||||
dlcKey = "dlc_instance_" + instanceIndex;
|
||||
}
|
||||
|
||||
// assign to SongSelectUI static key
|
||||
try { SongSelectUI.CurrentDlcKey = dlcKey; } catch { }
|
||||
|
||||
// mark selection first
|
||||
Select();
|
||||
|
||||
var s = GameObject.FindObjectOfType<SongSelectUI>();
|
||||
if (s != null)
|
||||
{
|
||||
@@ -262,4 +384,45 @@ public class dlcButton : MonoBehaviour
|
||||
|
||||
Debug.Log($"dlcButton: Loaded {dlcContent.Count} SongData entries for DLC id={id} (fallback search)");
|
||||
}
|
||||
|
||||
// Resolve dlcData after all buttons have been instantiated
|
||||
public void ResolveDlcData()
|
||||
{
|
||||
Debug.Log($"dlcButton.ResolveDlcData called on '{gameObject.name}'");
|
||||
|
||||
if (dlcDataSO != null)
|
||||
{
|
||||
Debug.Log($"dlcButton: dlcDataSO already assigned on '{gameObject.name}' -> {dlcDataSO.name}");
|
||||
ApplyDlcData(dlcDataSO);
|
||||
return;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
if (dlcID != null && int.TryParse(dlcID.text, out id))
|
||||
{
|
||||
Debug.Log($"dlcButton: Resolving by dlcID text {id} for '{gameObject.name}'");
|
||||
LoadDlcDataById(id);
|
||||
return;
|
||||
}
|
||||
|
||||
string goName = gameObject.name;
|
||||
if (!string.IsNullOrEmpty(goName))
|
||||
{
|
||||
var parts = goName.Split('_');
|
||||
int parsed = 0;
|
||||
if (parts.Length > 0 && int.TryParse(parts[0], out parsed))
|
||||
{
|
||||
Debug.Log($"dlcButton: Resolving by GameObject name prefix {parsed} for '{gameObject.name}'");
|
||||
LoadDlcDataById(parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.ResolveDlcData: could not parse id from GameObject name '{goName}'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"dlcButton.ResolveDlcData: no dlcID text and no name to parse for '{gameObject.name}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user