From 17e824e29ec4677d667693d8ad3e6dacb0cb7e3c Mon Sep 17 00:00:00 2001 From: "aube.lee" Date: Fri, 28 Feb 2025 00:55:35 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=20=EC=A2=85=EB=A3=8C=20=ED=9B=84=20=ED=81=B4=EB=A6=AC?= =?UTF-8?q?=EC=96=B4=20=EC=A0=95=EB=B3=B4=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F?= =?UTF-8?q?=20=EB=9E=AD=ED=82=B9=20=EC=A0=95=EB=B3=B4=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Backend/BackendClearDataManager.cs | 42 ++++ .../Backend/BackendClearDataManager.cs.meta | 11 ++ .../Scripts/Backend/BackendRankDataManager.cs | 187 ++++++++++++++++++ .../Backend/BackendRankDataManager.cs.meta | 11 ++ .../Scripts/Character/PlayerDataManager.cs | 13 ++ .../Gameton/Scripts/GameData/ClearData.cs | 35 ++++ ...ageClearData.cs.meta => ClearData.cs.meta} | 0 .../Scripts/GameData/StageClearData.cs | 34 ---- .../Gameton/Scripts/GameStage/StageManager.cs | 40 +++- 9 files changed, 329 insertions(+), 44 deletions(-) create mode 100644 Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs create mode 100644 Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs.meta create mode 100644 Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs create mode 100644 Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs.meta create mode 100644 Gameton-06/Assets/Gameton/Scripts/GameData/ClearData.cs rename Gameton-06/Assets/Gameton/Scripts/GameData/{StageClearData.cs.meta => ClearData.cs.meta} (100%) delete mode 100644 Gameton-06/Assets/Gameton/Scripts/GameData/StageClearData.cs diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs new file mode 100644 index 00000000..ae46ed84 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs @@ -0,0 +1,42 @@ +using System.Collections; +using System.Collections.Generic; +using BackEnd; +using UnityEngine; + +namespace TON +{ + /// + /// 뒤끝 서버 게임 클리어 데이터 관리 담당 클래스 + /// + public class BackendClearDataManager + { + // 테이블 이름 상수 + private const string CLEAR_TABLE = "CLEAR_DATA"; + + /// + /// 캐릭터 게임 클리어 시 row 삽입 + /// + public void InsertInitData(ClearData clearData) + { + Param param = new Param(); + param.Add("score", clearData.score); + param.Add("wave", clearData.wave); + param.Add("play_time", clearData.playTime); + param.Add("nickname", PlayerDataManager.Singleton.player.name); + + Backend.PlayerData.InsertData(CLEAR_TABLE, param, callback => + { + if (callback.IsSuccess()) + { + Debug.Log("BackendClearDataManager 데이터 삽입 성공"); + } + else + { + Debug.LogError("BackendClearDataManager 데이터 삽입 실패: " + callback.ToString()); + } + + }); + } + + } +} diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs.meta b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs.meta new file mode 100644 index 00000000..71da2679 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendClearDataManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54ac7e52b096e94489086a4bd8431f38 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs new file mode 100644 index 00000000..bf3560d8 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs @@ -0,0 +1,187 @@ +using System.Collections; +using System.Collections.Generic; +using BackEnd; +using UnityEngine; + +namespace TON +{ + /// + /// 뒤끝 서버 게임 클리어 데이터 관리 담당 클래스 + /// + public class BackendRankDataManager + { + // 테이블 이름 상수 + private const string RANK_TABLE = "RANK_DATA"; + + + // 내 게임 클리어 데이터 조회 + public void LoadMyRankData(System.Action onComplete) + { + ClearData clearData = new ClearData(); + + Backend.PlayerData.GetMyData(RANK_TABLE, callback => + { + if (callback.IsSuccess() == false) + { + Debug.Log("데이터 읽기 중에 문제가 발생했습니다 : " + callback.ToString()); + onComplete?.Invoke(null); + return; + } + + // 불러오기에는 성공했으나 데이터가 존재하지 않는 경우 + if (callback.IsSuccess() && callback.FlattenRows().Count <= 0) + { + Debug.Log("데이터가 존재하지 않습니다"); + InsertInitData(clearData, () => + { + // 초기 데이터 삽입 후 다시 데이터를 불러옴 + LoadDataAfterInsert(onComplete); + }); + return; + } + + // 1개 이상 데이터를 불러온 경우 + if (callback.FlattenRows().Count > 0) + { + clearData.nickname = callback.FlattenRows()[0]["nickname"].ToString(); + clearData.score = int.Parse(callback.FlattenRows()[0]["score"].ToString()); + clearData.wave = int.Parse(callback.FlattenRows()[0]["wave"].ToString()); + clearData.playTime = float.Parse(callback.FlattenRows()[0]["play_time"].ToString()); + + onComplete?.Invoke(clearData); // 성공 시 데이터 반환 + } + }); + } + + // 데이터 삽입 후 다시 불러오는 메소드 + private void LoadDataAfterInsert(System.Action onComplete) + { + Backend.PlayerData.GetMyData(RANK_TABLE, callback => + { + ClearData clearData = new ClearData(); + + if (callback.IsSuccess() && callback.FlattenRows().Count > 0) + { + clearData.nickname = callback.FlattenRows()[0]["nickname"].ToString(); + clearData.score = int.Parse(callback.FlattenRows()[0]["score"].ToString()); + clearData.wave = int.Parse(callback.FlattenRows()[0]["wave"].ToString()); + clearData.playTime = float.Parse(callback.FlattenRows()[0]["play_time"].ToString()); + } + + onComplete?.Invoke(clearData); + }); + } + + /// + /// 캐릭터 초기 생성 시 row 삽입 + /// + private void InsertInitData(ClearData clearData, System.Action onComplete = null) + { + Param param = new Param(); + param.Add("score", clearData.score); + param.Add("wave", clearData.wave); + param.Add("play_time", clearData.playTime); + param.Add("nickname", PlayerDataManager.Singleton.player.name); + + Backend.PlayerData.InsertData(RANK_TABLE, param, callback => + { + if (callback.IsSuccess()) + { + Debug.Log("초기 랭크 데이터 삽입 성공"); + } + else + { + Debug.LogError("초기 랭크 데이터 삽입 실패: " + callback.ToString()); + } + + onComplete?.Invoke(); + }); + } + + /// + /// 플레이 랭크 정보 업데이트 + /// + private void UpdateRankData(ClearData clearData, System.Action onComplete = null) + { + Param param = new Param(); + param.Add("score", clearData.score); + param.Add("wave", clearData.wave); + param.Add("play_time", clearData.playTime); + param.Add("nickname", clearData.nickname); + + Backend.PlayerData.UpdateMyLatestData(RANK_TABLE, param, callback => + { + if (callback.IsSuccess()) + { + Debug.Log("랭크 정보 업데이트 성공"); + onComplete?.Invoke(); + } + else + { + Debug.LogError("랭크 정보 업데이트 실패: " + callback.ToString()); + } + + }); + } + + /// + /// 캐릭터 플레이 랭크 정보 비교 후 업데이트 메소드 실행 + /// + public void CheckUpdateRankData(ClearData clearData, System.Action onComplete = null) + { + // 먼저 현재 테이블에서 최근 데이터를 가져옵니다 + Backend.GameData.GetMyData(RANK_TABLE, new Where(), 1, callback => + { + if (callback.IsSuccess()) + { + // 기존 데이터가 있는지 확인 + if (callback.FlattenRows().Count > 0) + { + // 최근 데이터 추출 + var latestData = callback.FlattenRows()[0]; + int latestWave = int.Parse(latestData["wave"].ToString()); + long latestScore = long.Parse(latestData["score"].ToString()); + float latestPlayTime = float.Parse(latestData["play_time"].ToString()); + + // 신규 데이터와 비교하여 업데이트 여부 결정 + bool shouldUpdate = false; + + // 업데이트 조건 설정 (예: 웨이브가 높거나, 웨이브가 같으면서 점수가 높거나, 웨이브와 점수가 같으면서 플레이 시간이 짧을 때) + if (clearData.wave > latestWave) + { + shouldUpdate = true; + } + else if (clearData.wave == latestWave && clearData.score > latestScore) + { + shouldUpdate = true; + } + else if (clearData.wave == latestWave && clearData.score == latestScore && clearData.playTime < latestPlayTime) + { + shouldUpdate = true; + } + + if (shouldUpdate) + { + UpdateRankData(clearData, onComplete); + } + else + { + Debug.Log("기존 기록이 더 좋아 업데이트하지 않음"); + } + } + else + { + // 기존 데이터가 없으면 무조건 삽입 + InsertInitData(clearData, onComplete); + } + } + else + { + Debug.LogError("기존 데이터 조회 실패: " + callback.ToString()); + } + }); + } + + + } +} diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs.meta b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs.meta new file mode 100644 index 00000000..1e10bf86 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendRankDataManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d3822a94a615414a8ca1cf53985f8c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs index fbb59d8e..3561dce8 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs @@ -72,6 +72,19 @@ namespace TON // UpdateUI(); }); } + + // 플레이어가 사망했을때 호출 + public void PlayerDeadEvent() + { + Invoke(nameof(ShowGameEndUI), 3f); + + } + private void ShowGameEndUI() + { + UIManager.Show(UIList.GameWinUI); + } + + // 공격력과 방어력 업데이트 private void UpdateStats(int currentLevel) { diff --git a/Gameton-06/Assets/Gameton/Scripts/GameData/ClearData.cs b/Gameton-06/Assets/Gameton/Scripts/GameData/ClearData.cs new file mode 100644 index 00000000..7f105292 --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/GameData/ClearData.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace TON +{ + [System.Serializable] + public class ClearData + { + public string nickname; + // 클리어한 웨이브 넘버 + public int wave; + // 클리어에 소요된 시간 + public float playTime; + // 획득 점수 + public int score; + + public ClearData() + { + nickname = ""; + wave = 0; + playTime = 0f; + score = 0; + } + + public void UpdateClearData(string nickname, int wave, float playTime, int score) + { + this.nickname = nickname; + this.wave = wave; + this.playTime = playTime; + this.score = score; + } + } +} diff --git a/Gameton-06/Assets/Gameton/Scripts/GameData/StageClearData.cs.meta b/Gameton-06/Assets/Gameton/Scripts/GameData/ClearData.cs.meta similarity index 100% rename from Gameton-06/Assets/Gameton/Scripts/GameData/StageClearData.cs.meta rename to Gameton-06/Assets/Gameton/Scripts/GameData/ClearData.cs.meta diff --git a/Gameton-06/Assets/Gameton/Scripts/GameData/StageClearData.cs b/Gameton-06/Assets/Gameton/Scripts/GameData/StageClearData.cs deleted file mode 100644 index 8cabf799..00000000 --- a/Gameton-06/Assets/Gameton/Scripts/GameData/StageClearData.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace TON -{ - [System.Serializable] - public class StageClearData - { - // 스테이지 클리어 데이터의 고유 id - public string id; - // 클리어한 캐릭터 아이디 - public string characterId; - // 클리어한 스테이지 아이디 - public string stageId; - // 클리어에 소요된 시간 - public float clearTime; - // 클리어 시간에 따른 별점 - public int starRating; - // 클리어한 날짜와 시간 정보 - public string dateTime; - - public StageClearData(string characterId, string stageId, float clearTime, int starRating) - { - id = $"SC{DateTime.UtcNow:yyyyMMddHHmmss}-{characterId}-{stageId}"; - this.characterId = characterId; - this.stageId = stageId; - this.clearTime = Mathf.Round(clearTime * 100f) / 100f; ; - this.starRating = starRating; - dateTime = DateTime.UtcNow.ToString(); - } - } -} diff --git a/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs b/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs index 17e2c533..ff4c4072 100644 --- a/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/GameStage/StageManager.cs @@ -7,10 +7,6 @@ namespace TON { public class StageManager : SingletonBase { - public List stageClearDatas { get; private set; } - [SerializeField] - public SerializableDictionary bestStageClearDict = new SerializableDictionary(); - // 현재 플레이 시간을 초 단위로 반환하는 프로퍼티 public float PlayTime => Time.time - stageStartTime; @@ -21,12 +17,28 @@ namespace TON private float stageStartTime; // 스테이지 시작 시간 + public ClearData TOP_RECORD { get; private set; } // lobby 화면에 기록 세팅할때 사용할 변수 + public List RankList { get; private set; } // 전체 랭킹 적용할 리스트 + + private BackendClearDataManager clearDataManager; + private BackendRankDataManager rankDataManager; public void Initialize() { + clearDataManager = new BackendClearDataManager(); + rankDataManager = new BackendRankDataManager(); + GetRankData(); } + public void GetRankData() + { + // 서버에서 내 클리어 데이터를 가져오고 가장 기록이 높은 정보를 세팅 + rankDataManager.LoadMyRankData(rankData => + { + TOP_RECORD.UpdateClearData(rankData.nickname, rankData.wave, rankData.playTime, rankData.score); + }); + } // 스테이지 시작 시 시작 정보 저장 public void StartStage() @@ -48,15 +60,23 @@ namespace TON waveCount = wave; } + /// + /// 게임 플레이 종료 시 클리어 정보 저장 로직 수행 + /// public void StageClear() { - string characterId = PlayerPrefs.GetString("BackendCustomID", string.Empty); - float clearTime = Time.time - stageStartTime; + float clearTime = PlayTime; - // TODO: UI 업데이트, 데이터 저장 로직 추가 - // StageClearData stageClearData = new StageClearData(characterId, stageId, clearTime, starCount); - // stageClearDatas.Add(stageClearData); - // SaveStageClearData(); + ClearData clearData = new ClearData(); + clearData.UpdateClearData(PlayerDataManager.Singleton.player.name, waveCount, clearTime, gameScore); + // clearData 저장 + clearDataManager.InsertInitData(clearData); + + // rankData 조회 후 비교 하여 저장 + rankDataManager.CheckUpdateRankData(clearData, () => + { + TOP_RECORD.UpdateClearData(clearData.nickname, clearData.wave, clearData.playTime, clearData.score); + }); }