feat: 캐릭터 스펙 정보 서버에 저장하도록 변경

This commit is contained in:
aube.lee
2025-03-09 20:46:25 +09:00
parent 9e3d3881da
commit 110dc3d86e
12 changed files with 188 additions and 103 deletions

View File

@@ -0,0 +1,114 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BackEnd;
namespace TON
{
/// <summary>
/// 뒤끝 서버 유저 데이터 관리 담당 클래스
/// </summary>
public class BackendPlayerDataManager
{
// 테이블 이름 상수
private const string USER_TABLE = "USER_DATA";
// PlayerDataManager에서 플레이어 데이터 로드
public void LoadMyPlayerData(System.Action<PlayerData> 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); // 성공 시 데이터 반환
}
});
}
/// <summary>
/// 캐릭터 초기 생성 시 row 삽입
/// </summary>
public void CreateNewPlayer(PlayerData playerData, System.Action<bool> 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<bool> 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);
}
});
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0eeb12a360b37e54c8dd15fae106c8c1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -58,8 +58,6 @@ namespace TON
public void Initialize() public void Initialize()
{ {
// int playerIndex = PlayerPrefs.GetInt("SelectedPlayerIndex", 0);
PlayerDataManager.Singleton.SetCurrentUserData();
playerData = PlayerDataManager.Singleton.player; playerData = PlayerDataManager.Singleton.player;
currentHP = maxHP = playerData.hp; currentHP = maxHP = playerData.hp;

View File

@@ -51,7 +51,7 @@ namespace TON
public void SetCurrentUserHeart() public void SetCurrentUserHeart()
{ {
characterId = PlayerPrefs.GetInt("SelectedPlayerIndex", -1); characterId = 0;
if (characterId > -1 && heartDatas.Count > 0) if (characterId > -1 && heartDatas.Count > 0)
{ {
currentHeartData = heartDatas[characterId]; currentHeartData = heartDatas[characterId];

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@@ -8,7 +9,6 @@ namespace TON
public class PlayerDataManager : SingletonBase<PlayerDataManager> public class PlayerDataManager : SingletonBase<PlayerDataManager>
{ {
// 사용자가 생성해둔 플레이어 데이터를 싱글톤으로 전역 사용하기 위함 // 사용자가 생성해둔 플레이어 데이터를 싱글톤으로 전역 사용하기 위함
public List<PlayerData> playersData { get; private set; }
public PlayerData player { get; private set; } public PlayerData player { get; private set; }
public int goldAmount { get; private set; } public int goldAmount { get; private set; }
public int fishAmount { get; private set; } public int fishAmount { get; private set; }
@@ -20,11 +20,13 @@ namespace TON
[SerializeField] private int expVariable = 50; // 경험치 변수 (조정 가능) [SerializeField] private int expVariable = 50; // 경험치 변수 (조정 가능)
[SerializeField] private float attackGrowthFactor = 50f; // 공격력 성장 변수 (조정 가능) [SerializeField] private float attackGrowthFactor = 50f; // 공격력 성장 변수 (조정 가능)
private BackendPlayerDataManager playerDataManager;
private BackendCashDataManager cashDataManager; private BackendCashDataManager cashDataManager;
private BackendItemDataManager itemDataManager; private BackendItemDataManager itemDataManager;
private void OnEnable() private void OnEnable()
{ {
playerDataManager = new BackendPlayerDataManager();
cashDataManager = new BackendCashDataManager(); cashDataManager = new BackendCashDataManager();
itemDataManager = new BackendItemDataManager(); itemDataManager = new BackendItemDataManager();
} }
@@ -38,17 +40,11 @@ namespace TON
private void LoadPlayerData() private void LoadPlayerData()
{ {
if (playersData != null) // * 사용자 정보 서버에서 조회
playerDataManager.LoadMyPlayerData(player =>
{ {
playersData.Clear(); SetPlayerData(player);
} });
JSONLoader.SaveJsonToPersistentData("player");
playersData = JSONLoader.LoadJsonFromPersistentData<List<PlayerData>>("player");
if (playersData == null)
{
playersData = new List<PlayerData>();
}
} }
private void LoadPlayerCashData() private void LoadPlayerCashData()
@@ -172,30 +168,25 @@ namespace TON
public void UpdatePlayerData() public void UpdatePlayerData()
{ {
Debug.Log($"player {player.level}: {player.attackPower}, {player.defensivePower}"); // 캐릭터 데이터 서버 업데이트
int index = playersData.FindIndex(x => x.id == player.id); playerDataManager.UpdatePlayerData(player, isSuccess =>
if (index > -1) {
if (isSuccess)
{ {
playersData[index] = player;
Assert.IsTrue(JSONLoader.SaveUpdatedJsonToPersistentData(playersData, "player"));
Initalize(); 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); requireLevelUpExp = GetRequiredExp(player.level);
} }
else
{
Debug.LogError("유효하지 않은 캐릭터 정보 입니다.");
}
} }
// 플레이어가 사망했을때 호출 // 플레이어가 사망했을때 호출
@@ -209,5 +200,12 @@ namespace TON
UIManager.Show<GameWinUI>(UIList.GameWinUI); UIManager.Show<GameWinUI>(UIList.GameWinUI);
} }
public void CreateNewPlayer(PlayerData player, System.Action<bool> onComplete = null)
{
playerDataManager.CreateNewPlayer(player, isSuccess =>
{
onComplete?.Invoke(isSuccess);
});
}
} }
} }

View File

@@ -8,21 +8,14 @@ namespace TON
{ {
public static bool SpawnPlayerCharacter() public static bool SpawnPlayerCharacter()
{ {
List<PlayerData> playerDatas = PlayerDataManager.Singleton.playersData; PlayerData playerData = PlayerDataManager.Singleton.player;
// 저장된 인덱스 가져오기
int selectedIndex = PlayerPrefs.GetInt("SelectedPlayerIndex", 0); string prefabName = playerData.type == "b" ? "TON.Player_B" : "TON.Player_W";
// 인덱스가 범위를 벗어나지 않는지 확인
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";
// Resources에서 프리팹 로드 // Resources에서 프리팹 로드
GameObject characterPrefab = Resources.Load<GameObject>($"Player/{prefabName}"); GameObject characterPrefab = Resources.Load<GameObject>($"Player/{prefabName}");
if (characterPrefab == null) if (characterPrefab == null)
{ {
Debug.LogError($"Failed to load character prefab: {playerDatas[selectedIndex].type}"); Debug.LogError($"Failed to load character prefab: {playerData.type}");
return false; return false;
} }
// TON.Player 오브젝트 찾기 // TON.Player 오브젝트 찾기

View File

@@ -51,7 +51,6 @@ namespace TON
// UIManager.Show<IngameOptionUI>(UIList.IngameOptionUI); // UIManager.Show<IngameOptionUI>(UIList.IngameOptionUI);
// UIManager.Show<SkillSettingUI>(UIList.SkillSettingUI); // UIManager.Show<SkillSettingUI>(UIList.SkillSettingUI);
PlayerDataManager.Singleton.Initalize(); PlayerDataManager.Singleton.Initalize();
PlayerDataManager.Singleton.SetCurrentUserData();
// UIManager.Show<ControllerUI>(UIList.ControllerUI); // UIManager.Show<ControllerUI>(UIList.ControllerUI);
// ControllerUI.Instance.Initalize(); // ControllerUI.Instance.Initalize();
// UIManager.Show<IngameUI>(UIList.IngameUI); // UIManager.Show<IngameUI>(UIList.IngameUI);

View File

@@ -10,7 +10,6 @@ namespace TON
TitleUI, // 게임 시작 화면 UI TitleUI, // 게임 시작 화면 UI
CharaterCreateUI, // 캐릭터 생성 UI CharaterCreateUI, // 캐릭터 생성 UI
CharaterSelectUI,
ControllerUI, // 캐릭터 컨트롤러 UI ControllerUI, // 캐릭터 컨트롤러 UI
LobbyUI, // 게임 로비 UI LobbyUI, // 게임 로비 UI
SkillSettingUI, // 스킬 세팅 팝업 UI SkillSettingUI, // 스킬 세팅 팝업 UI

View File

@@ -7,39 +7,23 @@ namespace TON
[System.Serializable] [System.Serializable]
public class PlayerData public class PlayerData
{ {
// 캐릭터 아이디 // 필드 선언 (외부 수정 방지)
public string id;
// 캐릭터 이미지 타입 (w/b)
public string type; public string type;
// 캐릭터 이름
public string name; public string name;
// 캐릭터 레벨 public int level = 1;
public int level; public int experience = 0;
// 캐릭터 경험치 public int hp = 100;
public int experience; public int mp = 100;
// 캐릭터 체력 public float attackPower = 50f;
public int hp; public float defensivePower = 30f;
// 캐릭터 마나(스킬 포인트) public int critical = 30;
public int mp;
// 기본 공격력
public float attackPower;
// 기본 방어력
public float defensivePower;
// 캐릭터 크리티컬 수치
public int critical;
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"; type = t == "BlackCat" ? "b" : "w";
name = n; name = n;
level = 1;
experience = 0;
hp = 100;
mp = 100;
attackPower = 50f;
defensivePower = 30f;
critical = 30;
} }
} }

View File

@@ -19,7 +19,6 @@ namespace TON
yield return null; yield return null;
} }
PlayerDataManager.Singleton.SetCurrentUserData();
SkillDataManager.Singleton.Initalize(); SkillDataManager.Singleton.Initalize();

View File

@@ -11,9 +11,8 @@ namespace TON
public class CharaterCreateUI : UIBase public class CharaterCreateUI : UIBase
{ {
[SerializeField] private Button cancelButton; // cancel 버튼 참조 [SerializeField] private Button cancelButton; // cancel 버튼 참조
[SerializeField] private Button confirmButton; // cancel 버튼 참조 [SerializeField] private Button confirmButton; // confirm 버튼 참조
[SerializeField] private Button createButton; // Create 버튼 참조 [SerializeField] private Button createButton; // Create 버튼 참조
[SerializeField] private List<PlayerData> playerDatas;
[SerializeField] private TextMeshProUGUI nicknameCondition; [SerializeField] private TextMeshProUGUI nicknameCondition;
@@ -26,8 +25,6 @@ namespace TON
private void Start() private void Start()
{ {
playerDatas = PlayerDataManager.Singleton.playersData;
// 처음에는 버튼을 비활성화 // 처음에는 버튼을 비활성화
createButton.interactable = false; createButton.interactable = false;
@@ -68,9 +65,6 @@ namespace TON
return; return;
} }
// 선택된 캐릭터 인덱스 정보를 저장 (다음 씬에서도 사용할 수 있도록)
PlayerPrefs.SetInt("SelectedPlayerIndex", 0);
// 캐릭터 이름 입력 모달 활성화 // 캐릭터 이름 입력 모달 활성화
characterCreateUI_Modal.SetActive(true); characterCreateUI_Modal.SetActive(true);
} }
@@ -120,21 +114,25 @@ namespace TON
if (success) if (success)
{ {
// 생성한 캐릭터를 저장한다 // 생성한 캐릭터를 저장한다
PlayerData player = new PlayerData(playerDatas.Count, selectedCharacter, nickname); PlayerData player = new PlayerData(selectedCharacter, nickname);
playerDatas.Add(player); PlayerDataManager.Singleton.SetPlayerData(player);
Assert.IsTrue(JSONLoader.SaveUpdatedJsonToPersistentData(playerDatas, "player"));
PlayerDataManager.Singleton.SetCurrentUserData();
// 뒤끝 서버 데이터 저장 로직 적용
PlayerDataManager.Singleton.CreateNewPlayer(player, isSuccess =>
{
if (isSuccess)
{
// 하트 시스템을 생성한다 // 하트 시스템을 생성한다
HeartDataManager.Singleton.CreateNewHeartSystem(playerDatas.Count); HeartDataManager.Singleton.CreateNewHeartSystem(0);
HeartDataManager.Singleton.SetCurrentUserHeart(); HeartDataManager.Singleton.SetCurrentUserHeart();
// 씬 변경 // 씬 변경
UIManager.Hide<CharaterCreateUI>(UIList.CharaterCreateUI); UIManager.Hide<CharaterCreateUI>(UIList.CharaterCreateUI);
Main.Singleton.ChangeScene(SceneType.Lobby); Main.Singleton.ChangeScene(SceneType.Lobby);
} }
});
}
else else
{ {
// 닉네임 중복체크 // 닉네임 중복체크

View File

@@ -6,7 +6,6 @@ namespace TON
{ {
public class TitleUI : UIBase public class TitleUI : UIBase
{ {
public CharaterSelectUI charaterSelectUI;
public void OnClickStartButton() public void OnClickStartButton()
{ {
@@ -17,25 +16,18 @@ namespace TON
{ {
yield return new WaitForSeconds(0.2f); // 0.2초 대기 yield return new WaitForSeconds(0.2f); // 0.2초 대기
// Main.Singleton?.ChangeScene(SceneType.Ingame);
UIManager.Hide<TitleUI>(UIList.TitleUI); UIManager.Hide<TitleUI>(UIList.TitleUI);
// 플레이어가 가지고 있는 캐릭터들의 데이터 불러옴 // 플레이어가 가지고 있는 캐릭터들의 데이터 불러옴
List<PlayerData> players = PlayerDataManager.Singleton.playersData; PlayerData player = PlayerDataManager.Singleton.player;
if (players == null || players.Count == 0) if (player == null)
{ {
// 현재 가지고 있는 캐릭터가 없다면 CharaterCreateUI 를 보여주고 // 현재 가지고 있는 캐릭터가 없다면 캐릭터 생성 화면으로 이동
UIManager.Show<CharaterCreateUI>(UIList.CharaterCreateUI); UIManager.Show<CharaterCreateUI>(UIList.CharaterCreateUI);
} }
else else
{ {
// 캐릭터가 있다면 내 캐릭터 목록에서 선택할 수 있도록 함
// UIManager.Show<CharaterSelectUI>(UIList.CharaterSelectUI);
// select 요소는 나중에 인게임 화면으로 바로 전환
PlayerPrefs.SetInt("SelectedPlayerIndex", 0);
PlayerDataManager.Singleton.SetCurrentUserData();
HeartDataManager.Singleton.SetCurrentUserHeart(); HeartDataManager.Singleton.SetCurrentUserHeart();
Main.Singleton.ChangeScene(SceneType.Lobby); Main.Singleton.ChangeScene(SceneType.Lobby);
} }