diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendPlayerDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendPlayerDataManager.cs new file mode 100644 index 00000000..e883a87b --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendPlayerDataManager.cs @@ -0,0 +1,114 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using BackEnd; + +namespace TON +{ + /// + /// 뒤끝 서버 유저 데이터 관리 담당 클래스 + /// + public class BackendPlayerDataManager + { + // 테이블 이름 상수 + private const string USER_TABLE = "USER_DATA"; + + // PlayerDataManager에서 플레이어 데이터 로드 + public void LoadMyPlayerData(System.Action onComplete) + { + PlayerData playerData = new PlayerData(); + + Backend.PlayerData.GetMyData(USER_TABLE, callback => + { + if (callback.IsSuccess() == false) + { + Debug.Log("데이터 읽기 중에 문제가 발생했습니다 : " + callback.ToString()); + Main.Singleton.SystemQuit(); + return; + } + + // 불러오기에는 성공했으나 데이터가 존재하지 않는 경우 + if (callback.IsSuccess() && callback.FlattenRows().Count <= 0) + { + Debug.Log("데이터가 존재하지 않습니다"); + onComplete.Invoke(null); + return; + } + + // 정상적으로 플레이어 데이터를 불러온 경우 + if (callback.FlattenRows().Count > 0) + { + playerData.type = callback.FlattenRows()[0]["type"].ToString(); + playerData.name = callback.FlattenRows()[0]["name"].ToString(); + playerData.level = int.Parse(callback.FlattenRows()[0]["level"].ToString()); + playerData.experience = int.Parse(callback.FlattenRows()[0]["experience"].ToString()); + playerData.hp = int.Parse(callback.FlattenRows()[0]["hp"].ToString()); + playerData.mp = int.Parse(callback.FlattenRows()[0]["mp"].ToString()); + playerData.attackPower = float.Parse(callback.FlattenRows()[0]["attackPower"].ToString()); + playerData.defensivePower = float.Parse(callback.FlattenRows()[0]["defensivePower"].ToString()); + playerData.critical = int.Parse(callback.FlattenRows()[0]["critical"].ToString()); + onComplete?.Invoke(playerData); // 성공 시 데이터 반환 + } + }); + } + + + /// + /// 캐릭터 초기 생성 시 row 삽입 + /// + public void CreateNewPlayer(PlayerData playerData, System.Action onComplete = null) + { + Param param = new Param(); + param.Add("type", playerData.type); + param.Add("name", playerData.name); + param.Add("level", playerData.level); + param.Add("experience", playerData.experience); + param.Add("hp", playerData.hp); + param.Add("mp", playerData.mp); + param.Add("attackPower", playerData.attackPower); + param.Add("defensivePower", playerData.defensivePower); + param.Add("critical", playerData.critical); + + Backend.PlayerData.InsertData(USER_TABLE, param, callback => + { + if (callback.IsSuccess()) + { + Debug.Log("캐릭터 생성 성공"); + onComplete?.Invoke(true); + } + else + { + Debug.LogError("캐릭터 생성 실패: " + callback.ToString()); + onComplete?.Invoke(false); + } + + }); + } + + + public void UpdatePlayerData(PlayerData playerData, System.Action onComplete = null) + { + Param param = new Param(); + param.Add("level", playerData.level); + param.Add("experience", playerData.experience); + param.Add("hp", playerData.hp); + param.Add("mp", playerData.mp); + param.Add("attackPower", playerData.attackPower); + param.Add("defensivePower", playerData.defensivePower); + + Backend.PlayerData.UpdateMyLatestData(USER_TABLE, param, (callback) => + { + if (callback.IsSuccess()) + { + Debug.Log("캐릭터 업데이트 성공"); + onComplete?.Invoke(true); + } + else + { + Debug.LogError("캐릭터 업데이트 실패: " + callback.ToString()); + onComplete?.Invoke(false); + } + }); + } + } +} diff --git a/Gameton-06/Assets/Gameton/Scripts/Backend/BackendPlayerDataManager.cs.meta b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendPlayerDataManager.cs.meta new file mode 100644 index 00000000..5f9c766a --- /dev/null +++ b/Gameton-06/Assets/Gameton/Scripts/Backend/BackendPlayerDataManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0eeb12a360b37e54c8dd15fae106c8c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Gameton-06/Assets/Gameton/Scripts/Character/CharacterBase.cs b/Gameton-06/Assets/Gameton/Scripts/Character/CharacterBase.cs index ab3afc99..33735851 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Character/CharacterBase.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Character/CharacterBase.cs @@ -58,8 +58,6 @@ namespace TON public void Initialize() { - // int playerIndex = PlayerPrefs.GetInt("SelectedPlayerIndex", 0); - PlayerDataManager.Singleton.SetCurrentUserData(); playerData = PlayerDataManager.Singleton.player; currentHP = maxHP = playerData.hp; @@ -257,7 +255,7 @@ namespace TON // 스킬 포인트가 부족하다면 스킬을 수행하지 못함 if (currentSP < skillBase.SkillData.mpConsumption) return; - // 스킬 매니저에서 스킬을 쏠 수 있는지 여부를 판단 + // 스킬 매니저에서 스킬을 쏠 수 있는지 여부를 판단 bool canExecute = SkillDataManager.Singleton.CanExecuteSkill(skillId); if (canExecute) { @@ -268,7 +266,7 @@ namespace TON // 스킬 애니메이터 실행 animator.Play("Skill Attack"); - // 스킬 매니저에 스킬 발사 요청 + // 스킬 매니저에 스킬 발사 요청 SkillDataManager.Singleton.ExecuteSkill(skillId, firePoint, lastDirection); // RecoverSP 가 이미 진행중인 경우 이중으로 코루틴을 실행하지 않도록 함함 diff --git a/Gameton-06/Assets/Gameton/Scripts/Character/Heart/HeartDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Character/Heart/HeartDataManager.cs index ee93d16d..7840962d 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Character/Heart/HeartDataManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Character/Heart/HeartDataManager.cs @@ -51,7 +51,7 @@ namespace TON public void SetCurrentUserHeart() { - characterId = PlayerPrefs.GetInt("SelectedPlayerIndex", -1); + characterId = 0; if (characterId > -1 && heartDatas.Count > 0) { currentHeartData = heartDatas[characterId]; diff --git a/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs b/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs index 7f0ac4f6..c85c4cfc 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Character/PlayerDataManager.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -8,7 +9,6 @@ namespace TON public class PlayerDataManager : SingletonBase { // 사용자가 생성해둔 플레이어 데이터를 싱글톤으로 전역 사용하기 위함 - public List playersData { get; private set; } public PlayerData player { get; private set; } public int goldAmount { get; private set; } public int fishAmount { get; private set; } @@ -20,11 +20,13 @@ namespace TON [SerializeField] private int expVariable = 50; // 경험치 변수 (조정 가능) [SerializeField] private float attackGrowthFactor = 50f; // 공격력 성장 변수 (조정 가능) + private BackendPlayerDataManager playerDataManager; private BackendCashDataManager cashDataManager; private BackendItemDataManager itemDataManager; private void OnEnable() { + playerDataManager = new BackendPlayerDataManager(); cashDataManager = new BackendCashDataManager(); itemDataManager = new BackendItemDataManager(); } @@ -38,17 +40,11 @@ namespace TON private void LoadPlayerData() { - if (playersData != null) + // * 사용자 정보 서버에서 조회 + playerDataManager.LoadMyPlayerData(player => { - playersData.Clear(); - } - - JSONLoader.SaveJsonToPersistentData("player"); - playersData = JSONLoader.LoadJsonFromPersistentData>("player"); - if (playersData == null) - { - playersData = new List(); - } + SetPlayerData(player); + }); } private void LoadPlayerCashData() @@ -172,30 +168,25 @@ namespace TON public void UpdatePlayerData() { - Debug.Log($"player {player.level}: {player.attackPower}, {player.defensivePower}"); - int index = playersData.FindIndex(x => x.id == player.id); - if (index > -1) + // 캐릭터 데이터 서버 업데이트 + playerDataManager.UpdatePlayerData(player, isSuccess => { - playersData[index] = player; - Assert.IsTrue(JSONLoader.SaveUpdatedJsonToPersistentData(playersData, "player")); - Initalize(); - } + if (isSuccess) + { + Initalize(); + } + }); } - public void SetCurrentUserData() + public void SetPlayerData(PlayerData playerData) { - if (playersData.Count > 0) + player = playerData; + + // 사용자 정보가 있을때만 레벨업 필요 초기값 세팅 + if (playerData != null) { - // 현재 플레이어 1개만 사용하므로 0번째 인덱스의 플레이어 데이터를 사용 - PlayerPrefs.SetInt("SelectedPlayerIndex", 0); - player = playersData[0]; - // 현재 플레이어의 정보를 세팅하고, 레벨업 필요 경험치 정보를 세팅 requireLevelUpExp = GetRequiredExp(player.level); } - else - { - Debug.LogError("유효하지 않은 캐릭터 정보 입니다."); - } } // 플레이어가 사망했을때 호출 @@ -209,5 +200,12 @@ namespace TON UIManager.Show(UIList.GameWinUI); } + public void CreateNewPlayer(PlayerData player, System.Action onComplete = null) + { + playerDataManager.CreateNewPlayer(player, isSuccess => + { + onComplete?.Invoke(isSuccess); + }); + } } } diff --git a/Gameton-06/Assets/Gameton/Scripts/Character/PlayerSpawner.cs b/Gameton-06/Assets/Gameton/Scripts/Character/PlayerSpawner.cs index b9c60d65..00ac17b2 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Character/PlayerSpawner.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Character/PlayerSpawner.cs @@ -8,21 +8,14 @@ namespace TON { public static bool SpawnPlayerCharacter() { - List playerDatas = PlayerDataManager.Singleton.playersData; - // 저장된 인덱스 가져오기 - int selectedIndex = PlayerPrefs.GetInt("SelectedPlayerIndex", 0); - // 인덱스가 범위를 벗어나지 않는지 확인 - if (selectedIndex < 0 || selectedIndex >= playerDatas.Count) - { - Debug.LogError($"Invalid player index: {selectedIndex}"); - return false; - } - string prefabName = playerDatas[selectedIndex].type == "b" ? "TON.Player_B" : "TON.Player_W"; + PlayerData playerData = PlayerDataManager.Singleton.player; + + string prefabName = playerData.type == "b" ? "TON.Player_B" : "TON.Player_W"; // Resources에서 프리팹 로드 GameObject characterPrefab = Resources.Load($"Player/{prefabName}"); if (characterPrefab == null) { - Debug.LogError($"Failed to load character prefab: {playerDatas[selectedIndex].type}"); + Debug.LogError($"Failed to load character prefab: {playerData.type}"); return false; } // TON.Player 오브젝트 찾기 diff --git a/Gameton-06/Assets/Gameton/Scripts/Common/BootStrapper.cs b/Gameton-06/Assets/Gameton/Scripts/Common/BootStrapper.cs index ec7004f4..449544f4 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Common/BootStrapper.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Common/BootStrapper.cs @@ -51,7 +51,6 @@ namespace TON // UIManager.Show(UIList.IngameOptionUI); // UIManager.Show(UIList.SkillSettingUI); PlayerDataManager.Singleton.Initalize(); - PlayerDataManager.Singleton.SetCurrentUserData(); // UIManager.Show(UIList.ControllerUI); // ControllerUI.Instance.Initalize(); // UIManager.Show(UIList.IngameUI); diff --git a/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs b/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs index fcad7997..7d1362bb 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Common/UIList.cs @@ -10,7 +10,6 @@ namespace TON TitleUI, // 게임 시작 화면 UI CharaterCreateUI, // 캐릭터 생성 UI - CharaterSelectUI, ControllerUI, // 캐릭터 컨트롤러 UI LobbyUI, // 게임 로비 UI SkillSettingUI, // 스킬 세팅 팝업 UI diff --git a/Gameton-06/Assets/Gameton/Scripts/GameData/PlayerData.cs b/Gameton-06/Assets/Gameton/Scripts/GameData/PlayerData.cs index 55d18eae..152d038f 100644 --- a/Gameton-06/Assets/Gameton/Scripts/GameData/PlayerData.cs +++ b/Gameton-06/Assets/Gameton/Scripts/GameData/PlayerData.cs @@ -7,39 +7,23 @@ namespace TON [System.Serializable] public class PlayerData { - // 캐릭터 아이디 - public string id; - // 캐릭터 이미지 타입 (w/b) + // 필드 선언 (외부 수정 방지) public string type; - // 캐릭터 이름 public string name; - // 캐릭터 레벨 - public int level; - // 캐릭터 경험치 - public int experience; - // 캐릭터 체력 - public int hp; - // 캐릭터 마나(스킬 포인트) - public int mp; - // 기본 공격력 - public float attackPower; - // 기본 방어력 - public float defensivePower; - // 캐릭터 크리티컬 수치 - public int critical; + public int level = 1; + public int experience = 0; + public int hp = 100; + public int mp = 100; + public float attackPower = 50f; + public float defensivePower = 30f; + public int critical = 30; - public PlayerData(int i, string t, string n) + public PlayerData() : this("w", "") { } + + public PlayerData(string t, string n) { - id = $"P{i:000}"; type = t == "BlackCat" ? "b" : "w"; name = n; - level = 1; - experience = 0; - hp = 100; - mp = 100; - attackPower = 50f; - defensivePower = 30f; - critical = 30; } } diff --git a/Gameton-06/Assets/Gameton/Scripts/Scenes/LobbyScene.cs b/Gameton-06/Assets/Gameton/Scripts/Scenes/LobbyScene.cs index 6cb8059b..fc966510 100644 --- a/Gameton-06/Assets/Gameton/Scripts/Scenes/LobbyScene.cs +++ b/Gameton-06/Assets/Gameton/Scripts/Scenes/LobbyScene.cs @@ -19,7 +19,6 @@ namespace TON yield return null; } - PlayerDataManager.Singleton.SetCurrentUserData(); SkillDataManager.Singleton.Initalize(); diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/CharaterCreateUI.cs b/Gameton-06/Assets/Gameton/Scripts/UI/CharaterCreateUI.cs index 87db93a0..80d3d002 100644 --- a/Gameton-06/Assets/Gameton/Scripts/UI/CharaterCreateUI.cs +++ b/Gameton-06/Assets/Gameton/Scripts/UI/CharaterCreateUI.cs @@ -11,9 +11,8 @@ namespace TON public class CharaterCreateUI : UIBase { [SerializeField] private Button cancelButton; // cancel 버튼 참조 - [SerializeField] private Button confirmButton; // cancel 버튼 참조 + [SerializeField] private Button confirmButton; // confirm 버튼 참조 [SerializeField] private Button createButton; // Create 버튼 참조 - [SerializeField] private List playerDatas; [SerializeField] private TextMeshProUGUI nicknameCondition; @@ -26,8 +25,6 @@ namespace TON private void Start() { - playerDatas = PlayerDataManager.Singleton.playersData; - // 처음에는 버튼을 비활성화 createButton.interactable = false; @@ -68,9 +65,6 @@ namespace TON return; } - // 선택된 캐릭터 인덱스 정보를 저장 (다음 씬에서도 사용할 수 있도록) - PlayerPrefs.SetInt("SelectedPlayerIndex", 0); - // 캐릭터 이름 입력 모달 활성화 characterCreateUI_Modal.SetActive(true); } @@ -120,20 +114,24 @@ namespace TON if (success) { // 생성한 캐릭터를 저장한다 - PlayerData player = new PlayerData(playerDatas.Count, selectedCharacter, nickname); - playerDatas.Add(player); - Assert.IsTrue(JSONLoader.SaveUpdatedJsonToPersistentData(playerDatas, "player")); + PlayerData player = new PlayerData(selectedCharacter, nickname); + PlayerDataManager.Singleton.SetPlayerData(player); - PlayerDataManager.Singleton.SetCurrentUserData(); + // 뒤끝 서버 데이터 저장 로직 적용 + PlayerDataManager.Singleton.CreateNewPlayer(player, isSuccess => + { + if (isSuccess) + { + // 하트 시스템을 생성한다 + HeartDataManager.Singleton.CreateNewHeartSystem(0); + HeartDataManager.Singleton.SetCurrentUserHeart(); - // 하트 시스템을 생성한다 - HeartDataManager.Singleton.CreateNewHeartSystem(playerDatas.Count); - HeartDataManager.Singleton.SetCurrentUserHeart(); + // 씬 변경 + UIManager.Hide(UIList.CharaterCreateUI); + Main.Singleton.ChangeScene(SceneType.Lobby); + } + }); - // 씬 변경 - UIManager.Hide(UIList.CharaterCreateUI); - - Main.Singleton.ChangeScene(SceneType.Lobby); } else { diff --git a/Gameton-06/Assets/Gameton/Scripts/UI/TitleUI.cs b/Gameton-06/Assets/Gameton/Scripts/UI/TitleUI.cs index 46b558e1..14f1bf04 100644 --- a/Gameton-06/Assets/Gameton/Scripts/UI/TitleUI.cs +++ b/Gameton-06/Assets/Gameton/Scripts/UI/TitleUI.cs @@ -6,7 +6,6 @@ namespace TON { public class TitleUI : UIBase { - public CharaterSelectUI charaterSelectUI; public void OnClickStartButton() { @@ -17,25 +16,18 @@ namespace TON { yield return new WaitForSeconds(0.2f); // 0.2초 대기 - // Main.Singleton?.ChangeScene(SceneType.Ingame); UIManager.Hide(UIList.TitleUI); // 플레이어가 가지고 있는 캐릭터들의 데이터 불러옴 - List players = PlayerDataManager.Singleton.playersData; + PlayerData player = PlayerDataManager.Singleton.player; - if (players == null || players.Count == 0) + if (player == null) { - // 현재 가지고 있는 캐릭터가 없다면 CharaterCreateUI 를 보여주고 + // 현재 가지고 있는 캐릭터가 없다면 캐릭터 생성 화면으로 이동 UIManager.Show(UIList.CharaterCreateUI); } else { - // 캐릭터가 있다면 내 캐릭터 목록에서 선택할 수 있도록 함 - // UIManager.Show(UIList.CharaterSelectUI); - - // select 요소는 나중에 인게임 화면으로 바로 전환 - PlayerPrefs.SetInt("SelectedPlayerIndex", 0); - PlayerDataManager.Singleton.SetCurrentUserData(); HeartDataManager.Singleton.SetCurrentUserHeart(); Main.Singleton.ChangeScene(SceneType.Lobby); }