153 lines
5.5 KiB
C#
153 lines
5.5 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using DG.Tweening;
|
||
using Sirenix.OdinInspector;
|
||
using SLSUtilities.WwiseAssistance;
|
||
using TMPro;
|
||
using UniRx;
|
||
using UnityEngine;
|
||
using UnityEngine.Serialization;
|
||
using UnityEngine.UI;
|
||
|
||
namespace Ichni.Menu
|
||
{
|
||
public partial class SongSelectionTab : MonoBehaviour
|
||
{
|
||
private SongListControllerUI songListController => MenuManager.instance.songSelectionUIPage.songListController;
|
||
|
||
/// <summary>
|
||
/// 供锁标识和预览滤镜使用的运行时状态。进入歌曲前必须调用 <see cref="RefreshUnlockState"/>
|
||
/// 重新计算,不能把缓存的显示状态当作最终授权结果。
|
||
/// </summary>
|
||
public bool isLocked;
|
||
|
||
public SongItemData connectedSong;
|
||
public TMP_Text songNameText;
|
||
public TMP_Text composerNameText;
|
||
|
||
public Button quickSwitchButton;
|
||
|
||
public float distanceToCenter;
|
||
|
||
[Title("背景图&选中处理")]
|
||
public RectTransform background;
|
||
public Image selectedImage;
|
||
public Image unselectedImage;
|
||
public Image lockMark;
|
||
|
||
public void SetUpTab(SongItemData song)
|
||
{
|
||
connectedSong = song;
|
||
songNameText.text = song.displaySongName;
|
||
composerNameText.text = song.composer;
|
||
|
||
RefreshUnlockState();
|
||
|
||
quickSwitchButton.onClick.AddListener(() =>
|
||
{
|
||
if (MenuManager.instance.songSelectionUIPage.songListController.selectedTab == this)
|
||
{
|
||
SongSelectionUIPage songSelectionUIPage = MenuManager.instance.songSelectionUIPage;
|
||
|
||
// 快速进入会绕过 PlaySongUI 的 Button.interactable,必须在此处重复保护空难度状态。
|
||
if (songSelectionUIPage.selectedSong == null || songSelectionUIPage.selectedDifficulty == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 快速进入与标准 Play 共用统一的章节 + 歌曲授权检查,不能因 UI 状态过期而绕过锁定。
|
||
if (!RefreshUnlockState())
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (MenuManager.instance.isEnteringGame)
|
||
{
|
||
return;
|
||
}
|
||
|
||
MenuManager.instance.isEnteringGame = true;
|
||
|
||
InformationTransistor.instance.SetInformation(
|
||
ChapterSelectionManager.instance.currentChapter,
|
||
songSelectionUIPage.selectedSong,
|
||
songSelectionUIPage.selectedDifficulty);
|
||
|
||
AudioManager.Post(AK.EVENTS.ENTERTOGAME);
|
||
SongSelectionManager.instance.StopPreviewSong();
|
||
|
||
MenuManager.instance.transitionUIPage.FadeIn();
|
||
|
||
Observable.Timer(TimeSpan.FromSeconds(0.6f)).Subscribe(_ =>
|
||
{
|
||
MenuManager.instance.EnterGame();
|
||
});
|
||
}
|
||
else
|
||
{
|
||
StartCoroutine(MenuManager.instance.songSelectionUIPage.songListController.SnapToTab(this));
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重新计算当前 Tab 是否锁定,并同步锁图标。
|
||
/// 章节本身被锁定时,即使歌曲规则无条件开放,也仍然视为不可进入。
|
||
/// </summary>
|
||
/// <returns>返回 true 表示当前章节和歌曲均允许进入。</returns>
|
||
public bool RefreshUnlockState()
|
||
{
|
||
UnlockSaveModule unlockSaveModule = GameSaveManager.instance?.UnlockSaveModule;
|
||
ChapterSelectionUnit currentChapter = ChapterSelectionManager.instance?.currentChapter;
|
||
isLocked = unlockSaveModule == null || !unlockSaveModule.CanEnterSong(currentChapter, connectedSong);
|
||
|
||
if (lockMark != null)
|
||
{
|
||
lockMark.gameObject.SetActive(isLocked);
|
||
}
|
||
|
||
return !isLocked;
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
RectTransform centerPoint = songListController.centerPoint;
|
||
RectTransform rectTransform = GetComponent<RectTransform>();
|
||
|
||
distanceToCenter = Mathf.Abs(centerPoint.position.y - rectTransform.position.y);
|
||
float x1 = Mathf.Sqrt(distanceToCenter) * 25 + 25;
|
||
float x2 = distanceToCenter * 5 + 25;
|
||
float x3 = Mathf.Pow(distanceToCenter, 2) / 10f + 25;
|
||
rectTransform.GetChild(0).GetComponent<RectTransform>().anchoredPosition = new Vector2(x2, 0);
|
||
}
|
||
}
|
||
|
||
public partial class SongSelectionTab
|
||
{
|
||
public void SetSelection(bool isSelected)
|
||
{
|
||
if (isSelected)
|
||
{
|
||
background.DOScaleY(1.2f, 0.25f)
|
||
.SetEase(Ease.OutQuad)
|
||
.Play();
|
||
|
||
selectedImage.DOFade(1, 0.25f)
|
||
.SetEase(Ease.OutQuad)
|
||
.Play();
|
||
}
|
||
else
|
||
{
|
||
background.DOScaleY(1f, 0.25f)
|
||
.SetEase(Ease.OutQuad)
|
||
.Play();
|
||
|
||
selectedImage.DOFade(0, 0.25f)
|
||
.SetEase(Ease.OutQuad)
|
||
.Play();
|
||
}
|
||
}
|
||
}
|
||
}
|