很多更新,服务端连接,新UI和系统
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using GameServer.Client;
|
||||
|
||||
public class SongDetailsUI : MonoBehaviour
|
||||
{
|
||||
[Header("this_song_SO")]
|
||||
public ScriptableObject this_song_SO;
|
||||
|
||||
[Header("ranking")]
|
||||
public Button rankingButton;
|
||||
public rankingList rkl;
|
||||
|
||||
[Header("room")]
|
||||
public Button roomButton;
|
||||
public GameObject askPrefab;
|
||||
public GameObject roomDetailsPrefab;
|
||||
public GameObject roomRankingPrefab;
|
||||
public Transform roomSpawnPoint;
|
||||
|
||||
[Header("basic UI")]
|
||||
public Image song_bgImage;
|
||||
|
||||
@@ -52,6 +67,182 @@ public class SongDetailsUI : MonoBehaviour
|
||||
public Button Button_IM;
|
||||
|
||||
private SongData currentSong;
|
||||
private GameObject spawnedAskInstance;
|
||||
private GameObject spawnedRoomDetailsInstance;
|
||||
|
||||
private SongData ResolveCurrentSong()
|
||||
{
|
||||
if (currentSong != null)
|
||||
{
|
||||
return currentSong;
|
||||
}
|
||||
|
||||
if (this_song_SO is SongData soSong)
|
||||
{
|
||||
currentSong = soSong;
|
||||
return currentSong;
|
||||
}
|
||||
|
||||
if (SongDataHolder.SelectedSongData != null)
|
||||
{
|
||||
currentSong = SongDataHolder.SelectedSongData;
|
||||
return currentSong;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
currentSong = ResolveCurrentSong();
|
||||
|
||||
ArenaRoomService roomService = ArenaRoomService.Instance;
|
||||
if (roomService != null)
|
||||
{
|
||||
roomService.OnRoomSnapshotChanged -= HandleArenaRoomSnapshotChanged;
|
||||
roomService.OnRoomSnapshotChanged += HandleArenaRoomSnapshotChanged;
|
||||
HandleArenaRoomSnapshotChanged(roomService.CurrentRoom);
|
||||
}
|
||||
|
||||
if (roomButton == null)
|
||||
{
|
||||
roomButton = FindButtonByName("roomButton");
|
||||
}
|
||||
|
||||
if (rankingButton != null)
|
||||
{
|
||||
rankingButton.onClick.RemoveListener(OnRankingButtonClicked);
|
||||
rankingButton.onClick.AddListener(OnRankingButtonClicked);
|
||||
}
|
||||
|
||||
if (roomButton != null)
|
||||
{
|
||||
roomButton.onClick.RemoveListener(OnRoomButtonClicked);
|
||||
roomButton.onClick.AddListener(OnRoomButtonClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
ArenaRoomService roomService = ArenaRoomService.Instance;
|
||||
if (roomService != null)
|
||||
{
|
||||
roomService.OnRoomSnapshotChanged -= HandleArenaRoomSnapshotChanged;
|
||||
}
|
||||
|
||||
if (rankingButton != null)
|
||||
{
|
||||
rankingButton.onClick.RemoveListener(OnRankingButtonClicked);
|
||||
}
|
||||
|
||||
if (roomButton != null)
|
||||
{
|
||||
roomButton.onClick.RemoveListener(OnRoomButtonClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleArenaRoomSnapshotChanged(ArenaRoomSnapshot snapshot)
|
||||
{
|
||||
if (snapshot == null || string.IsNullOrWhiteSpace(snapshot.song_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!int.TryParse(snapshot.song_id, out int songId))
|
||||
{
|
||||
Debug.LogWarning($"[SongDetailsUI] Invalid arena room song_id: {snapshot.song_id}");
|
||||
return;
|
||||
}
|
||||
|
||||
SongDataLibrary library = SongDataLibrary.Instance;
|
||||
if (library == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] SongDataLibrary is not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
SongData roomSong = library.GetSongDataByID(songId);
|
||||
if (roomSong == null)
|
||||
{
|
||||
Debug.LogWarning($"[SongDetailsUI] Room song not found for song_id={songId}");
|
||||
return;
|
||||
}
|
||||
|
||||
int roomDifficultyId = ConvertDifficultyKeyToId(snapshot.difficulty);
|
||||
bool sameSong = currentSong != null && currentSong.songID == roomSong.songID;
|
||||
bool sameDifficulty = sameSong && currentSong.thisLevel_selectedDifficultyID == roomDifficultyId;
|
||||
if (sameSong && sameDifficulty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ApplySongSelection(roomSong, roomDifficultyId);
|
||||
}
|
||||
|
||||
private void ApplySongSelection(SongData song, int difficultyId)
|
||||
{
|
||||
if (song == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
difficultyId = Mathf.Clamp(difficultyId, 0, 3);
|
||||
song.thisLevel_selectedDifficultyID = difficultyId;
|
||||
currentSong = song;
|
||||
this_song_SO = song;
|
||||
SongDataHolder.SelectedSongData = song;
|
||||
id_of_thisSong = song.songID;
|
||||
|
||||
RefreshSongPresentation(song);
|
||||
SetDifficultyButtons(difficultyId);
|
||||
UpdateDifficultyUI(difficultyId);
|
||||
}
|
||||
|
||||
private void RefreshSongPresentation(SongData song)
|
||||
{
|
||||
if (song == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (song_bgImage != null) song_bgImage.sprite = song.backgroudPIC;
|
||||
if (songNameText != null) songNameText.text = song.songName;
|
||||
if (artistNameText != null) artistNameText.text = song.artistName;
|
||||
if (painterNameText != null) painterNameText.text = song.painter;
|
||||
if (charterNameText != null) charterNameText.text = song.level_creator;
|
||||
if (dlcNameText != null) dlcNameText.text = song.belongsTo_whichDLC;
|
||||
if (songSerialNumberText != null) songSerialNumberText.text = song.songID.ToString();
|
||||
if (bpmText != null) bpmText.text = "BPM : " + song.bpm.ToString();
|
||||
if (profound_image != null) profound_image.sprite = song.fullscreen_songPicture;
|
||||
if (timeSpentText != null) timeSpentText.text = "PlayTime: " + song.time_totalPlayingTime.ToString("F0") + "s";
|
||||
if (enterTimeText != null) enterTimeText.text = "PlayCount: " + song.game_enterTimes.ToString();
|
||||
if (detail_informations_text != null)
|
||||
{
|
||||
detail_informations_text.text =
|
||||
$"{song.artistName} - {song.songName} | 曲绘: {song.painter} | 制谱: {song.level_creator} | DLC: {song.belongsTo_whichDLC}";
|
||||
}
|
||||
}
|
||||
|
||||
private int ConvertDifficultyKeyToId(string difficultyKey)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(difficultyKey))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
switch (difficultyKey.Trim().ToLowerInvariant())
|
||||
{
|
||||
case "ez":
|
||||
return 0;
|
||||
case "hd":
|
||||
return 1;
|
||||
case "im":
|
||||
return 3;
|
||||
case "in":
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
@@ -114,6 +305,286 @@ public class SongDetailsUI : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRankingButtonClicked()
|
||||
{
|
||||
SongData song = ResolveCurrentSong();
|
||||
if (song == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Ranking button clicked, but no song is currently selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rkl == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Ranking button clicked, but rankingList reference is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
rkl.Open(song.songID.ToString(), song.songName);
|
||||
}
|
||||
|
||||
public async void OnRoomButtonClicked()
|
||||
{
|
||||
SongData song = ResolveCurrentSong();
|
||||
if (song == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Room button clicked, but no song is currently selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaRoomService roomService = ArenaRoomService.Instance;
|
||||
if (roomService == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] ArenaRoomService is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (roomService.IsInRoom)
|
||||
{
|
||||
try
|
||||
{
|
||||
await roomService.RefreshRoomInfo();
|
||||
ShowRoomDetails(roomService);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[SongDetailsUI] Failed to refresh current room: {ex.Message}");
|
||||
DestroyRoomDetailsInstance();
|
||||
ShowRoomAsk(song, roomService);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyRoomDetailsInstance();
|
||||
ShowRoomAsk(song, roomService);
|
||||
}
|
||||
|
||||
public void OpenRoomDetailsForCurrentRoom()
|
||||
{
|
||||
ArenaRoomService roomService = ArenaRoomService.Instance;
|
||||
if (roomService == null || !roomService.IsInRoom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HandleArenaRoomSnapshotChanged(roomService.CurrentRoom);
|
||||
DestroyAskInstance();
|
||||
ShowRoomDetails(roomService);
|
||||
}
|
||||
|
||||
private void ShowRoomAsk(SongData song, ArenaRoomService roomService)
|
||||
{
|
||||
if (spawnedAskInstance != null)
|
||||
{
|
||||
Destroy(spawnedAskInstance);
|
||||
}
|
||||
|
||||
GameObject askTemplate = ResolveAskTemplate();
|
||||
if (askTemplate == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Ask prefab/template is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
spawnedAskInstance = Instantiate(askTemplate, ResolveRoomSpawnParent(), false);
|
||||
PrepareSpawnedPanel(spawnedAskInstance);
|
||||
|
||||
roomAsk ask = spawnedAskInstance.GetComponent<roomAsk>();
|
||||
if (ask == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Spawned ask object has no roomAsk component.");
|
||||
return;
|
||||
}
|
||||
|
||||
ask.Bind(
|
||||
async () =>
|
||||
{
|
||||
await roomService.CreateRoom(
|
||||
song.songID.ToString(),
|
||||
song.songName,
|
||||
ResolveSelectedDifficultyKey(song),
|
||||
null);
|
||||
try
|
||||
{
|
||||
await roomService.RefreshRoomInfo();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[SongDetailsUI] Refresh room info after create failed: {ex.Message}");
|
||||
}
|
||||
DestroyAskInstance();
|
||||
ShowRoomDetails(roomService);
|
||||
},
|
||||
async roomCode =>
|
||||
{
|
||||
await roomService.JoinRoom(roomCode, null);
|
||||
try
|
||||
{
|
||||
await roomService.RefreshRoomInfo();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[SongDetailsUI] Refresh room info after join failed: {ex.Message}");
|
||||
}
|
||||
DestroyAskInstance();
|
||||
ShowRoomDetails(roomService);
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowRoomDetails(ArenaRoomService roomService)
|
||||
{
|
||||
if (spawnedRoomDetailsInstance != null)
|
||||
{
|
||||
roomDetails existing = spawnedRoomDetailsInstance.GetComponent<roomDetails>();
|
||||
if (existing != null)
|
||||
{
|
||||
existing.ConfigureRoomRanking(roomRankingPrefab, ResolveRoomSpawnParent());
|
||||
existing.Bind(roomService);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject roomTemplate = ResolveRoomDetailsTemplate();
|
||||
if (roomTemplate == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Room details prefab/template is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
spawnedRoomDetailsInstance = Instantiate(roomTemplate, ResolveRoomSpawnParent(), false);
|
||||
PrepareSpawnedPanel(spawnedRoomDetailsInstance);
|
||||
|
||||
roomDetails details = spawnedRoomDetailsInstance.GetComponent<roomDetails>();
|
||||
if (details == null)
|
||||
{
|
||||
Debug.LogWarning("[SongDetailsUI] Spawned room details object has no roomDetails component.");
|
||||
return;
|
||||
}
|
||||
|
||||
details.ConfigureRoomRanking(roomRankingPrefab, ResolveRoomSpawnParent());
|
||||
details.Bind(roomService);
|
||||
}
|
||||
|
||||
private void DestroyAskInstance()
|
||||
{
|
||||
if (spawnedAskInstance != null)
|
||||
{
|
||||
Destroy(spawnedAskInstance);
|
||||
spawnedAskInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyRoomDetailsInstance()
|
||||
{
|
||||
if (spawnedRoomDetailsInstance != null)
|
||||
{
|
||||
Destroy(spawnedRoomDetailsInstance);
|
||||
spawnedRoomDetailsInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
private GameObject ResolveAskTemplate()
|
||||
{
|
||||
if (askPrefab != null)
|
||||
{
|
||||
return askPrefab;
|
||||
}
|
||||
|
||||
roomAsk sceneTemplate = FindSceneObject<roomAsk>();
|
||||
if (sceneTemplate != null)
|
||||
{
|
||||
sceneTemplate.gameObject.SetActive(false);
|
||||
return sceneTemplate.gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private GameObject ResolveRoomDetailsTemplate()
|
||||
{
|
||||
if (roomDetailsPrefab != null)
|
||||
{
|
||||
return roomDetailsPrefab;
|
||||
}
|
||||
|
||||
roomDetails sceneTemplate = FindSceneObject<roomDetails>();
|
||||
if (sceneTemplate != null)
|
||||
{
|
||||
sceneTemplate.gameObject.SetActive(false);
|
||||
return sceneTemplate.gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Transform ResolveRoomSpawnParent()
|
||||
{
|
||||
if (roomSpawnPoint != null && roomSpawnPoint.gameObject.activeInHierarchy && roomSpawnPoint.lossyScale.sqrMagnitude > 0.0001f)
|
||||
{
|
||||
return roomSpawnPoint;
|
||||
}
|
||||
|
||||
Canvas canvas = null;
|
||||
if (roomButton != null)
|
||||
{
|
||||
canvas = roomButton.GetComponentsInParent<Canvas>(true).FirstOrDefault();
|
||||
}
|
||||
|
||||
if (canvas == null)
|
||||
{
|
||||
canvas = GetComponentsInParent<Canvas>(true).FirstOrDefault();
|
||||
}
|
||||
|
||||
if (canvas != null)
|
||||
{
|
||||
return canvas.transform;
|
||||
}
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
private void PrepareSpawnedPanel(GameObject panel)
|
||||
{
|
||||
if (panel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
panel.SetActive(true);
|
||||
RectTransform rect = panel.GetComponent<RectTransform>();
|
||||
if (rect != null)
|
||||
{
|
||||
rect.localScale = Vector3.one;
|
||||
rect.anchoredPosition3D = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
private Button FindButtonByName(string objectName)
|
||||
{
|
||||
Button[] buttons = Resources.FindObjectsOfTypeAll<Button>();
|
||||
return buttons.FirstOrDefault(b => b != null
|
||||
&& b.gameObject.scene.IsValid()
|
||||
&& string.Equals(b.gameObject.name, objectName, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private static T FindSceneObject<T>() where T : Component
|
||||
{
|
||||
T[] all = Resources.FindObjectsOfTypeAll<T>();
|
||||
return all.FirstOrDefault(item => item != null && item.gameObject.scene.IsValid());
|
||||
}
|
||||
|
||||
private string ResolveSelectedDifficultyKey(SongData song)
|
||||
{
|
||||
int selectedDifficulty = song != null ? song.thisLevel_selectedDifficultyID : 2;
|
||||
return selectedDifficulty switch
|
||||
{
|
||||
0 => "ez",
|
||||
1 => "hd",
|
||||
3 => "im",
|
||||
_ => "in",
|
||||
};
|
||||
}
|
||||
|
||||
private void SetDifficultyButtons(int selectedDifficulty)
|
||||
{
|
||||
Button_EZ.image.color = new Color(1, 1, 1, selectedDifficulty == 0 ? 1 : 0);
|
||||
|
||||
@@ -9,6 +9,10 @@ using Bansonic;
|
||||
|
||||
public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
[Header("ranking")]
|
||||
public Button rankingButton;
|
||||
public rankingList s_rl;
|
||||
|
||||
[Header("Music Controls")]
|
||||
public Button playpausebutton;
|
||||
public Button stopbutton;
|
||||
@@ -270,6 +274,17 @@ public class selected_songInfo : MonoBehaviour
|
||||
LogVerbose("quickEnter_gamePlay is null in OnEnable");
|
||||
}
|
||||
|
||||
if (rankingButton != null)
|
||||
{
|
||||
rankingButton.onClick.RemoveListener(OnRankingButtonClicked);
|
||||
rankingButton.onClick.AddListener(OnRankingButtonClicked);
|
||||
LogVerbose("rankingButton listener added");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogVerbose("rankingButton is null in OnEnable");
|
||||
}
|
||||
|
||||
BindPromptButtons();
|
||||
}
|
||||
|
||||
@@ -287,6 +302,10 @@ public class selected_songInfo : MonoBehaviour
|
||||
{
|
||||
quickEnter_gamePlay.onClick.RemoveListener(OnQuickEnterClicked);
|
||||
}
|
||||
if (rankingButton != null)
|
||||
{
|
||||
rankingButton.onClick.RemoveListener(OnRankingButtonClicked);
|
||||
}
|
||||
|
||||
UnbindPromptButtons();
|
||||
_promptAwaitingChoice = false;
|
||||
@@ -365,6 +384,35 @@ public class selected_songInfo : MonoBehaviour
|
||||
LogVerbose($"selected_songInfo.Start: SongDataHolder.SelectedSongData is {(SongDataHolder.SelectedSongData == null ? "NULL" : SongDataHolder.SelectedSongData.songName)}");
|
||||
}
|
||||
|
||||
private SongData GetCurrentSelectedSong()
|
||||
{
|
||||
if (SongDataHolder.SelectedSongData != null)
|
||||
{
|
||||
return SongDataHolder.SelectedSongData;
|
||||
}
|
||||
|
||||
LogVerbose("GetCurrentSelectedSong: SongDataHolder.SelectedSongData is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
public void OnRankingButtonClicked()
|
||||
{
|
||||
SongData song = GetCurrentSelectedSong();
|
||||
if (song == null)
|
||||
{
|
||||
Debug.LogWarning("[selected_songInfo] Ranking button clicked, but no song is currently selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_rl == null)
|
||||
{
|
||||
Debug.LogWarning("[selected_songInfo] Ranking button clicked, but rankingList reference is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
s_rl.Open(song.songID.ToString(), song.songName);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
UpdateMusicPlaybackProgress();
|
||||
|
||||
Reference in New Issue
Block a user