일단 나는 다른분들이 Json을 사용하는건 많이 봐왔으나 보기만 했을 뿐 이론이나 내가 손댄적은 한번도 없었기에 저건 저장하는 기능의 일부구나 라고만 생각했지 그 외에 알고있는건 단 하나도 없었다.
그런 상태에서 시작하려고 하니 이론적으로 공부해도 무슨소린지 이해가 안되어 어려운점이 많았다..
일단 GameManager에서는 유저 데이터의 경로를 설정하고, 정보를 저장할 수 있도록 했다.
public class GameManager : MonoBehaviour
{
string userPath; // 사용자 목록 지정 경로
private void Awake()
{
// Assets 폴더 내 SaveData 폴더를 경로로 설정, userData 이름으로 저장
userPath = Path.Combine(Application.dataPath, "SaveData", "userData.json");
}
public void LoadUsers()
{
// 경로에 Json 파일이 존재하지 않으면 바로 종료
if (!File.Exists(userPath))
{
return;
}
// JsonUtillityManager를 통해 Json을 UserDataList 객체로 변환
UserDataList userDataList = JsonUtilityManager.LoadUserDataList(userPath);
if (userDataList == null)
{
return;
}
// 모든 유저 데이터 리스트(userDataList)에서 현재 로그인한 유저 ID와 일치하는 데이터를 찾음
foreach (var user in userDataList.userDatas)
{
// 유저ID는 PlayerPrefs 사용
if (PlayerPrefs.GetString("userid") == user.UserID)
{
userData = new UserData(user.UserID, user.Password, user.UserName, user.Balance, user.Cash);
}
}
}
}
일단 현재 유저정보를 어떻게 가져올지 고민도 많이하고 방법을 몰라 헤메던 와중 생각난게 PlayerPrefs였고 이 방식을 사용했는데, 이는 현재 로그인한 유저의 정보와 JSON에 저장된 유저 데이터를 비교하여 필요한 정보만 가져오기 위해 사용했다.
그리고 중간에 UserDataList userDataList = JsonUtilityManager.LoadUserDataList(userPath); 이 코드는 따로 스크립트 없이 작성되었으나, 추후 송금기능에 사용할 일이 생겨 JsonUtilityManager 클래스를 작성하여 작성해주었다.
이부분은 송금기능에서,
public class SaveManager : MonoBehaviour
{
public static string path = Path.Combine(Application.dataPath, "SaveData", "userData.json");
// 유저 데이터 저장 - 역직렬화
public static void SaveUserData(UserData userData)
{
string json = File.ReadAllText(path);
UserDataList userDataList = JsonUtility.FromJson<UserDataList>(json);
foreach (var user in userDataList.userDatas)
{
if (PlayerPrefs.GetString("userid") == user.UserID)
{
user.UserID = GameManager.Instance.userData.UserID;
user.Password = GameManager.Instance.userData.Password;
user.UserName = GameManager.Instance.userData.UserName;
user.Balance = GameManager.Instance.userData.Balance;
user.Cash = GameManager.Instance.userData.Cash;
}
}
string data = JsonUtility.ToJson(userDataList, true); // JSON 보기 쉽게 저장
File.WriteAllText(path, data);
}
}
정보 저장을 위한 코드도 작성해주었다.
userData.json을 읽어 UserDataList 객체로 변환한 후, 현재 로그인한 유저의 정보를 GameManager의 userData 값으로 업데이트하고 변경된 데이터를 다시 JSON으로 변환해 저장한다.

이제 로그인..!
public class LoginController : MonoBehaviour
{
public InputField UserID;
public InputField Password;
public void Login()
{
// 로그인한 유저 정보를 PlayerPrefs에 저장
string id = UserID.text;
PlayerPrefs.SetString("userid", id);
string password = Password.text;
// 유저 데이터가 없으면 정보를 불러옴
if (GameManager.Instance.users.Count == 0)
{
GameManager.Instance.LoadUsers();
}
string path = Path.Combine(Application.dataPath, "SaveData", "userData.json");
// ID, PW가 비어있거나 null인경우 종료
if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(password))
{
return;
}
if (File.Exists(path))
{
string jsonData = File.ReadAllText(path);
UserDataList userDataList = JsonUtility.FromJson<UserDataList>(jsonData);
// 입력한 정보와 일치하는 유저 찾기
UserData userData = userDataList.userDatas.Find(userData => userData.UserID == id && userData.Password == password);
if (userData != null)
{
OnLoginSuccess(); // 로그인 성공 처리
}
else
{
OnLoginErrorObjBtn(); // 로그인 실패 처리
}
}
}
}
로그인 기능은 사용자가 입력한 ID와 비밀번호를 확인하고, 데이터 파일에서 일치하는 유저 정보를 찾아 로그인 혹은 실패처리를 할수있게 해주었다.
로그인 성공은 메인씬으로 이동하게, 실패는 SetActive를 사용해 에러창을 뜨게 해주었다.

로그인이 있으면 회원가입도 있어야 하니 같이 만들어야지..
public class SignupController : MonoBehaviour
{
public void SignUp()
{
// 아이디생성
string id = UserID.text;
string path = Path.Combine(Application.dataPath, "SaveData", "userData.json");
if (File.Exists(path))
{
string jsonData = File.ReadAllText(path);
UserDataList userDataList = JsonUtility.FromJson<UserDataList>(jsonData);
foreach (UserData userData in userDataList.userDatas)
{
if (userData.UserID == id)
{
SignMessage.text = "중복되는 ID가 있습니다.";
return;
}
}
}
// 비밀번호확인
string pw = Password.text;
string check = PasswordCheck.text;
if (pw != check)
{
SignMessage.text = "비밀번호가 일치하지 않습니다.";
return;
}
SignUpSuccess();
SignMessage.text = "회원가입이 완료되었습니다.";
}
// 회원가입 등록
public void SignUpSuccess()
{
// 초기값, 금액은 0, 0
UserData userData = new UserData(UserID.text, Password.text, UserName.text, 0, 0);
string path = Path.Combine(Application.dataPath, "SaveData", $"{userData.UserID}.json");
UserDataList userDataList = new UserDataList();
if (File.Exists(path))
{
string existingData = File.ReadAllText(path);
userDataList = JsonUtility.FromJson<UserDataList>(existingData);
}
userDataList.userDatas.Add(userData);
string newData = JsonUtility.ToJson(userDataList, true);
File.WriteAllText(path, newData);
AddToUserDataList(userData);
}
public void AddToUserDataList(UserData userData)
{
string path = Path.Combine(Application.dataPath, "SaveData", "userData.json");
UserDataList userDataList = new UserDataList();
if (File.Exists(path))
{
string existingData = File.ReadAllText(path);
userDataList = JsonUtility.FromJson<UserDataList>(existingData);
}
userDataList.userDatas.Add(userData);
string newData = JsonUtility.ToJson(userDataList, true);
File.WriteAllText(path, newData);
}
}
- SignUp() : 아이디 중복체크, 비밀번호 확인 후 회원가입이 가능하게 처리 (아이디 중복 혹은 비밀번호가 다를경우 에러메세지 출력
- SignUpSuccess() : 회원가입 등록, UserData 객체 셍성 및 아이디/비밀번호/이름/초기금액(0)이 설정되며 해당경로에 이미 데이터가 존재하면 기존 데이터를 읽어오고 없으면 새로 생성
- AddToUserDataList(UserData userData) : 전체 유저 목록에 추가, 기존에 저장된 json 파일을 읽어와 UserDataList 객체를 생성한 후 새로운 UserData를 추가



보라색 칸엔 회원가입과 관련된 메세지가 나오게 해주었고 에러창을 하나하나 뜨게 해주는건 번거로우니 조건에 따라 메세지 출력을 다르게 해주었다. "회원가입이 완료되었습니다." 메세지가 뜨면 정상적으로 회원가입 완료다.

'Unity > Unity Study' 카테고리의 다른 글
[Unity] 클리키 게임 팀 프로젝트 중, 여러번 눌림 현상 (0) | 2025.04.03 |
---|---|
[Unity] 개인과제, ATM 만들기 - 송금 (0) | 2025.03.31 |
[Unity] 개인과제, ATM 만들기 - PlayerPrefs를 통한 유저 저장 (0) | 2025.03.26 |
[Unity] 개인과제, ATM 만들기 - 입금, 송금 (0) | 2025.03.25 |
[Unity] 3D Surviver 팀 프로젝트 중, Player 사망처리 및 애니메이션 (0) | 2025.03.25 |