본문 바로가기
유니티

Day 51 - 멀티플레이 사용자 데이터 저장 및 로드 전략

by shin0707 2024. 12. 10.
728x90

 

  • 주제

>>  데이터 저장 방식 선택

>>  사용자 데이터 모델링

>>  클라우드 저장소 연동

>>  데이터 저장의 최적화


  • 공부내용

멀티플레이 게임에서는 각 플레이어의 데이터를 저장하고, 로그인 시 이를 로드하는 기능이 필수적이다. 오늘은 사용자 데이터 관리 전략을 알아보겠다.

 

1. 데이터 저장 방식 선택

1-1. 로컬 저장

플레이어의 데이터를 클라이언트에 저장하는 방식이다.

  • 장점: 서버 부하 감소
  • 단점: 데이터 손실 가능성, 부정행위 위험

Unity에서는 PlayerPrefs를 사용해 간단히 데이터를 저장할 수 있다.

PlayerPrefs.SetInt("HighScore", 1000);
PlayerPrefs.Save();

 

 

1-2. 서버 저장

플레이어 데이터를 서버에 저장하여 안전성과 확장성을 보장한다.

  • 장점: 데이터 손실 방지, 중앙 관리 가능
  • 단점: 서버 비용 발생

2. 사용자 데이터 모델링

[Serializable]
public class PlayerData
{
    public string playerId;
    public int highScore;
    public int coins;
}

3. 클라우드 저장소 연동

Google Firebase를 사용하면 클라우드 기반 데이터 저장을 쉽게 구현할 수 있다.

3-1. Firebase로 데이터 저장

FirebaseDatabase.DefaultInstance.GetReference("players")
    .Child(playerId).SetRawJsonValueAsync(JsonUtility.ToJson(playerData));

 

 

3-2. Firebase에서 데이터 로드

FirebaseDatabase.DefaultInstance.GetReference("players")
    .Child(playerId).GetValueAsync().ContinueWith(task => {
        if (task.IsCompleted)
        {
            string json = task.Result.GetRawJsonValue();
            PlayerData playerData = JsonUtility.FromJson<PlayerData>(json);
        }
    });

 


 

4. 데이터 저장의 최적화

 

  • 필요한 데이터만 저장: 불필요한 데이터를 저장하지 않는다.
  • 주기적인 저장: 특정 이벤트 발생 시 데이터 저장을 호출한다.
    플레이어가 스테이지 클리어, 아이템 획득, 레벨 업 등 주요 행동을 했을 때만 데이터를 저장한다.

 

4-1. 코드 예제: 특정 이벤트 발생 시 데이터 저장

using UnityEngine;
using System;

public class PlayerDataManager : MonoBehaviour
{
    [Serializable]
    public class PlayerData
    {
        public string playerId;
        public int highScore;
        public int level;
        public int coins;
    }

    private PlayerData currentPlayerData;

    private void Start()
    {
        // 초기 데이터 로드
        LoadPlayerData();
    }

    public void OnStageClear(int score)
    {
        currentPlayerData.highScore = Mathf.Max(currentPlayerData.highScore, score);
        currentPlayerData.level += 1; // 레벨 증가
        SavePlayerData();
    }

    public void OnItemCollected(int coinAmount)
    {
        currentPlayerData.coins += coinAmount;
        SavePlayerData();
    }

    private void SavePlayerData()
    {
        string jsonData = JsonUtility.ToJson(currentPlayerData);
        PlayerPrefs.SetString("PlayerData", jsonData);
        PlayerPrefs.Save(); // 로컬 저장소에 데이터 저장
        Debug.Log("Player data saved: " + jsonData);
    }

    private void LoadPlayerData()
    {
        string jsonData = PlayerPrefs.GetString("PlayerData", "");
        if (!string.IsNullOrEmpty(jsonData))
        {
            currentPlayerData = JsonUtility.FromJson<PlayerData>(jsonData);
            Debug.Log("Player data loaded: " + jsonData);
        }
        else
        {
            currentPlayerData = new PlayerData { playerId = "Player1", highScore = 0, level = 1, coins = 0 };
            Debug.Log("No data found. Initializing new player data.");
        }
    }
}

 

코드 설명

 

  • PlayerData 모델
    • 플레이어 데이터를 직렬화하여 저장한다.
  • 이벤트 발생 시 데이터 업데이트
    • OnStageClear와 OnItemCollected 메서드를 통해 특정 이벤트가 발생할 때만 데이터를 저장한다.
  • 로컬 저장 방식
    • PlayerPrefs를 사용하여 간단히 로컬 저장을 구현했다.
    • 클라우드 서버 저장으로 확장하려면 Firebase 또는 REST API를 사용할 수 있다.
  • 최적화 포인트
    • 불필요한 이벤트에서는 데이터를 저장하지 않아 서버와 클라이언트 리소스를 절약한다.
    • 데이터를 주기적으로 저장하는 대신, 중요한 순간에만 저장하여 최적화를 극대화한다.

 

4-2. 코드 예제: 주기적인 저장

private float saveInterval = 30f; // 30초마다 저장
private float timer;

private void Update()
{
    timer += Time.deltaTime;
    if (timer >= saveInterval)
    {
        SavePlayerData();
        timer = 0f;
    }
}

 

 

728x90
반응형