diff --git a/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/Rank Box/Rank Box.prefab b/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/Rank Box/Rank Box.prefab index 9f9bdf93..1235df95 100644 --- a/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/Rank Box/Rank Box.prefab +++ b/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/Rank Box/Rank Box.prefab @@ -678,10 +678,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 1167917753387700438} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 350, y: 50} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 60.5, y: 0} + m_SizeDelta: {x: -121, y: 50} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &5593457180591604332 CanvasRenderer: @@ -744,7 +744,7 @@ MonoBehaviour: m_enableAutoSizing: 0 m_fontSizeMin: 18 m_fontSizeMax: 72 - m_fontStyle: 0 + m_fontStyle: 16 m_HorizontalAlignment: 1 m_VerticalAlignment: 1024 m_textAlignment: 65535 @@ -851,8 +851,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 60, y: -35} - m_SizeDelta: {x: -280, y: 50} + m_AnchoredPosition: {x: 75, y: -35} + m_SizeDelta: {x: -250, y: 50} m_Pivot: {x: 0.5, y: 1} --- !u!1 &4380570898053347355 GameObject: @@ -1479,6 +1479,7 @@ GameObject: - component: {fileID: 178720843269296823} - component: {fileID: 2461189433906269157} - component: {fileID: 8806745900426442480} + - component: {fileID: 1836485528427718722} m_Layer: 5 m_Name: Rank Box m_TagString: Untagged @@ -1546,3 +1547,22 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!114 &1836485528427718722 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8201404655171497624} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e5f063d17b315ac49b03acf8e9dd20b4, type: 3} + m_Name: + m_EditorClassIdentifier: + rankBoxImage: {fileID: 8201404655171497624} + pawImage: {fileID: 4683561962985573316} + playerName: {fileID: 314859685783772368} + rankNumber: {fileID: 3138926961904540219} + waveText: {fileID: 8627601446384052062} + scoreText: {fileID: 815654436774351460} + playTimeText: {fileID: 5222120854099221483} diff --git a/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/UI.RankingUI.prefab b/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/UI.RankingUI.prefab index ad5c5c1a..c79fef49 100644 --- a/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/UI.RankingUI.prefab +++ b/Gameton-06/Assets/Gameton/Resources/UI/Prefabs/UI.RankingUI.prefab @@ -167,13 +167,13 @@ MonoBehaviour: m_faceColor: serializedVersion: 2 rgba: 4294967295 - m_fontSize: 80 - m_fontSizeBase: 80 + m_fontSize: 72 + m_fontSizeBase: 72 m_fontWeight: 400 m_enableAutoSizing: 0 m_fontSizeMin: 18 m_fontSizeMax: 72 - m_fontStyle: 0 + m_fontStyle: 32 m_HorizontalAlignment: 2 m_VerticalAlignment: 256 m_textAlignment: 65535 @@ -330,7 +330,7 @@ MonoBehaviour: m_HandleRect: {fileID: 2996482217434952235} m_Direction: 2 m_Value: 0 - m_Size: 0.81078446 + m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: @@ -790,7 +790,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 89.48933} + m_AnchoredPosition: {x: 0, y: 0.000049850816} m_SizeDelta: {x: 0, y: 300} m_Pivot: {x: 0, y: 1} --- !u!1 &3043442581440476734 @@ -1073,6 +1073,7 @@ GameObject: - component: {fileID: 9118730511966541160} - component: {fileID: 2113469555973075398} - component: {fileID: 1160619946675334543} + - component: {fileID: 1392314752875031212} m_Layer: 5 m_Name: UI.RankingUI m_TagString: Untagged @@ -1165,7 +1166,29 @@ MonoBehaviour: m_BlockingObjects: 0 m_BlockingMask: serializedVersion: 2 - m_Bits: 4294967295 + m_Bits: 575 +--- !u!114 &1392314752875031212 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3554716968759600474} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4a019ce503091b94d814688735c831ce, type: 3} + m_Name: + m_EditorClassIdentifier: + scrollRect: {fileID: 6409563792739250610} + rankBoxPrefab: {fileID: 1836485528427718722, guid: 64f6711fc3dfade4f8926564be683890, type: 3} + uiPrefabList: [] + createRankList: [] + pawImage: {fileID: 3737414318957097033} + playerName: {fileID: 3819162921920848464} + rankNumber: {fileID: 6166724200374471149} + waveText: {fileID: 5214693156015332225} + scoreText: {fileID: 6316769929460910027} + playTimeText: {fileID: 3719967942584180839} --- !u!1 &3676414504436749960 GameObject: m_ObjectHideFlags: 0 @@ -1900,7 +1923,19 @@ MonoBehaviour: m_TargetGraphic: {fileID: 6021362233292978298} m_OnClick: m_PersistentCalls: - m_Calls: [] + m_Calls: + - m_Target: {fileID: 1392314752875031212} + m_TargetAssemblyTypeName: TON.RankingUI, Assembly-CSharp + m_MethodName: OnClickCloseButton + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 --- !u!1 &6292012439216301528 GameObject: m_ObjectHideFlags: 0 @@ -2866,55 +2901,59 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 3398201985880822359, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 3398201985880822359, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 3398201985880822359, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 465.33334 objectReference: {fileID: 0} - target: {fileID: 3398201985880822359, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -50 objectReference: {fileID: 0} - target: {fileID: 6905585838350402351, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6905585838350402351, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6905585838350402351, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 75 objectReference: {fileID: 0} - target: {fileID: 6905585838350402351, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -50 objectReference: {fileID: 0} - target: {fileID: 8201404655171497624, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_Name value: Rank Box objectReference: {fileID: 0} + - target: {fileID: 8201404655171497624, guid: 64f6711fc3dfade4f8926564be683890, type: 3} + propertyPath: m_IsActive + value: 0 + objectReference: {fileID: 0} - target: {fileID: 9137538600224533238, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9137538600224533238, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9137538600224533238, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 262.6667 objectReference: {fileID: 0} - target: {fileID: 9137538600224533238, guid: 64f6711fc3dfade4f8926564be683890, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -50 objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs index ece92eb1..d3a07202 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs @@ -184,9 +184,9 @@ namespace TON /// - /// 플레이어 랭킹 리스트 불러오기기 + /// 플레이어 랭킹 리스트 불러오기 /// - public void GetRankData(System.Action> onComplete = null) + public void GetRankData(System.Action onComplete = null) { // 가져올 필드 지정 (모든 필드를 가져오려면 null 사용) string[] select = new string[] { "nickname", "wave", "score", "play_time" }; @@ -207,30 +207,7 @@ namespace TON LitJson.JsonData rankData = bro.GetReturnValuetoJSON()["rows"]; Debug.Log("가져온 데이터 수: " + rankData.Count); - // ClearData 리스트 생성 및 변환 - List clearDataList = new List(); - - for (int i = 0; i < rankData.Count; i++) - { - LitJson.JsonData row = rankData[i]; - clearDataList.Add(new ClearData - { - nickname = row["nickname"].ToString(), - wave = int.Parse(row["wave"].ToString()), - score = int.Parse(row["score"].ToString()), - playTime = float.Parse(row["play_time"].ToString()), - }); - } - - // 정렬 (score 내림차순, playTime 오름차순) - clearDataList.Sort((a, b) => - { - if (a.score != b.score) return b.score.CompareTo(a.score); - return a.playTime.CompareTo(b.playTime); - }); - - onComplete?.Invoke(clearDataList); - + onComplete?.Invoke(rankData); } else { diff --git a/Gameton-06/Assets/Gameton/Scripts/Common/AssetManager.cs b/Gameton-06/Assets/Gameton/Scripts/Common/AssetManager.cs index 41759e3c..cb653a2e 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Common/AssetManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Common/AssetManager.cs @@ -38,5 +38,39 @@ namespace TON { return LoadAsset($"UI/Monster Portrait/wave{wave}_monster", out result); } + + public bool LoadRankPawIcon(int rank, out Sprite result) + { + if (rank < 4) + { + // Rank 1, 2, 3일 때 실행할 코드 + return LoadAsset($"UI/Ranking Paw/paw_{rank}th", out result); + } + else if (rank >= 4 && rank <= 20) + { + // Rank 4~20일 때 실행할 코드 + return LoadAsset($"UI/Ranking Paw/paw_4th", out result); + } + else if (rank >= 21 && rank <= 50) + { + // Rank 21~50일 때 실행할 코드 + return LoadAsset($"UI/Ranking Paw/paw_5th", out result); + } + else if (rank >= 51 || rank == -1) + { + // Rank 51 이상일 때 실행할 코드 + return LoadAsset($"UI/Ranking Paw/paw_6th", out result); + } + else + { + result = null; + return false; + } + } + + public bool LoadMyRankBoxImage(out Sprite result) + { + return LoadAsset($"UI/Ranking Paw/my_rank_box", out result); + } } } diff --git a/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs b/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs index 5ff316a0..fb2b8829 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs @@ -14,23 +14,19 @@ namespace TON ControllerUI, // 캐릭터 컨트롤러 UI LobbyUI, // 게임 로비 UI SkillSettingUI, // 스킬 세팅 팝업 UI - + RankingUI, // 랭킹 UI IngameUI, // 인게임 표시 UI - OptionUI, // 화면 우측 상단 골드, 인벤토리, 옵션 버튼 UI - - PANEL_END, + POPUP_START, LoadingUI, - GameOverUI, // 게임 오버 시 노출되는 UI GameWinUI, // 게임 클리어 시 노출되는 UI PauseUI, // 일시중지 버튼 선택 시 노출되는 UI - GoldPopup, POPUP_END, diff --git a/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs b/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs index ffccff36..b47d4e60 100644 --- a/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs @@ -29,6 +29,7 @@ namespace TON rankDataManager = new BackendRankDataManager(); GetMyRankData(); + GetRankList(); } public void GetMyRankData() @@ -90,15 +91,34 @@ namespace TON public void GetRankList() { - rankDataManager.GetRankData(rankList => + rankDataManager.GetRankData(rankData => { - int i = 1; - rankList.ForEach((data) => - Debug.Log($"Rank {i++}: {data.nickname}, Wave {data.wave}, Score {data.score}, PlayTime {data.playTime}")); + for (int i = 0; i < rankData.Count; i++) + { + LitJson.JsonData row = rankData[i]; + RankList.Add(new ClearData + { + nickname = row["nickname"].ToString(), + wave = int.Parse(row["wave"].ToString()), + score = int.Parse(row["score"].ToString()), + playTime = float.Parse(row["play_time"].ToString()), + }); + } + + // 정렬 (score 내림차순, playTime 오름차순) + RankList.Sort((a, b) => + { + if (a.score != b.score) return b.score.CompareTo(a.score); + return a.playTime.CompareTo(b.playTime); + }); }); } - + public int GetMyRankNumber() + { + int rankNumber = RankList.FindIndex(data => data.nickname.Equals(TOP_RECORD.nickname)); + return rankNumber; + } } } diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/LobbyUI.cs b/Gameton-06/Assets/Gameton/Scripts/UI/LobbyUI.cs index 27c46553..b0b9fb54 100644 --- a/Gameton-06/Assets/Gameton/Scripts/UI/LobbyUI.cs +++ b/Gameton-06/Assets/Gameton/Scripts/UI/LobbyUI.cs @@ -105,9 +105,8 @@ namespace TON public void OnClickRankingButton() { - // TODO: 랭킹 UI 추가 - StageManager.Singleton.GetRankList(); - // UIManager.Show(UIList.RankingUI); + // 랭킹 UI 추가 + UIManager.Show(UIList.RankingUI); } public void OnClickShopButton() diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI.cs b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI.cs new file mode 100644 index 00000000..b50aecf4 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI.cs @@ -0,0 +1,97 @@ +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.Assertions; +using UnityEngine.UI; + +namespace TON +{ + public class RankingUI : UIBase + { + public static RankingUI Instance => UIManager.Singleton.GetUI(UIList.RankingUI); + + // 전체 랭킹 리스트를 스크롤 형식으로 구현하기 위함 + public ScrollRect scrollRect; + public RankingUI_RankBox rankBoxPrefab; + public List uiPrefabList = new List(); + public List createRankList = new List(); + + [SerializeField] private GameObject pawImage; + [SerializeField] private TextMeshProUGUI playerName; + [SerializeField] private TextMeshProUGUI rankNumber; + [SerializeField] private TextMeshProUGUI waveText; + [SerializeField] private TextMeshProUGUI scoreText; + [SerializeField] private TextMeshProUGUI playTimeText; + + private void OnEnable() + { + // SetRankList(); + SetMyRankData(); + } + + private void SetMyRankData() + { + ClearData TOP_RECORD = StageManager.Singleton.TOP_RECORD; + // int myRankNumber = StageManager.Singleton.GetMyRankNumber(); + int myRankNumber = -1; + + playerName.text = TOP_RECORD.nickname; + rankNumber.text = myRankNumber > -1 ? $"{myRankNumber} th" : "Not Record"; + waveText.text = $"{TOP_RECORD.wave}"; + scoreText.text = $"{TOP_RECORD.score}"; + + int minutes = Mathf.FloorToInt(TOP_RECORD.playTime / 60f); + int seconds = Mathf.FloorToInt(TOP_RECORD.playTime % 60f); + playTimeText.text = $"{minutes:0}m {seconds:0}s"; + + SetPawIcon(myRankNumber); + } + + private void SetRankList() + { + // 이미 기존에 UI가 생성되어 있다면 삭제 + if (createRankList.Count > 0) + { + createRankList.Clear(); + } + if (uiPrefabList.Count > 0) + { + uiPrefabList.Clear(); + } + + List rankList = StageManager.Singleton.RankList; + + float y = 0; + for (int i = 0; i < rankList.Count; i++) + { + ClearData clearData = rankList[i]; + RankingUI_RankBox rankBox = Instantiate(rankBoxPrefab, scrollRect.content); + + rankBox.gameObject.SetActive(true); + rankBox.Initalize(i + 1, clearData); + createRankList.Add(rankBox); + + RectTransform rectTransform = rankBox.GetComponent(); + + uiPrefabList.Add(rectTransform); + uiPrefabList[i].anchoredPosition = new Vector2(0f, -y); + y += uiPrefabList[i].sizeDelta.y; + } + + scrollRect.content.sizeDelta = new Vector2(scrollRect.content.sizeDelta.x, y); + } + + private void SetPawIcon(int rank) + { + Sprite loadedPawImage = null; + Assert.IsTrue(AssetManager.Singleton.LoadRankPawIcon(rank, out loadedPawImage)); + pawImage.GetComponent().sprite = loadedPawImage; + } + + public void OnClickCloseButton() + { + UIManager.Hide(UIList.RankingUI); + } + } +} diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI.cs.meta b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI.cs.meta new file mode 100644 index 00000000..60cd8e20 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a019ce503091b94d814688735c831ce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI_RankBox.cs b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI_RankBox.cs new file mode 100644 index 00000000..e8fc1b9a --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI_RankBox.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.Assertions; +using UnityEngine.UI; + +namespace TON +{ + public class RankingUI_RankBox : MonoBehaviour + { + [SerializeField] private GameObject rankBoxImage; + [SerializeField] private GameObject pawImage; + [SerializeField] private TextMeshProUGUI playerName; + [SerializeField] private TextMeshProUGUI rankNumber; + [SerializeField] private TextMeshProUGUI waveText; + [SerializeField] private TextMeshProUGUI scoreText; + [SerializeField] private TextMeshProUGUI playTimeText; + + + public void Initalize(int rank, ClearData clearData) + { + playerName.text = clearData.nickname; + rankNumber.text = $"{rank} th"; + waveText.text = $"{clearData.wave}"; + scoreText.text = $"{clearData.score}"; + + int minutes = Mathf.FloorToInt(clearData.playTime / 60f); + int seconds = Mathf.FloorToInt(clearData.playTime % 60f); + playTimeText.text = $"{minutes:0}m {seconds:0}s"; + + SetPawIcon(rank); + SetMyRankBoxImage(); + } + + private void SetMyRankBoxImage() + { + Sprite loadedMyBoxImage = null; + Assert.IsTrue(AssetManager.Singleton.LoadMyRankBoxImage(out loadedMyBoxImage)); + rankBoxImage.GetComponent().sprite = loadedMyBoxImage; + } + + private void SetPawIcon(int rank) + { + Sprite loadedPawImage = null; + Assert.IsTrue(AssetManager.Singleton.LoadRankPawIcon(rank, out loadedPawImage)); + pawImage.GetComponent().sprite = loadedPawImage; + } + } +} diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI_RankBox.cs.meta b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI_RankBox.cs.meta new file mode 100644 index 00000000..0631e338 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/UI/RankingUI_RankBox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5f063d17b315ac49b03acf8e9dd20b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: