유니티

[유니티] EASY SAVE와 GPGS를 이용하여 클라우드 저장하기

HorseDragon 2023. 3. 5. 19:37

간신히 여기저기 물어가며 알아가면서 EASY SAVE와 GPGS를 이용하여 클라우드 저장하기에 성공.

EASY SAVE는 유니티 에셋에서 돈주고 사면 되고.. GPGS는 찾아보면 이용하는 방법이 잘 나와있기 때문에 하기 쉽다.

 

GPGS에 저장하는 형식은 byte이므로 ES3.LoadRawBytes를 이용해서 형식을 변경해주고 Save를 진행한다.

Load(또는 Read)의 경우에는 거꾸로 byte 형식의 데이터를 string(ES3 저장 형식)으로 변환시켜줘야한다.

Encoding.UTF8.GetString()을 이용해야 함.

 

EASY SAVE와 GPGS를 이용하여 깔끔하게 클라우드 저장 이용!

 

using UnityEngine;
using UnityEngine.UI;
using System.Text; //Encoding 사용
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using GooglePlayGames.BasicApi.SavedGame; //SavedGame 이용하는데 필요

public class GoogleLeaderboard : MonoBehaviour
{
	private string saveName = "GameCloudData";
    ISavedGameClient savedGameClient;    
    
    public void Start() 
    {       
        PlayGamesPlatform.Activate(); //PGPS 활성화, Social 기능 구현을 위해 필수적으로 필요
        Social.localUser.Authenticate(ProcessAuthentication); //로그인 확인, PGPS 활성화, Social 기능 구현을 위해 필수적으로 필요
    }
    
    void ProcessAuthentication (bool success) //Social기능의 ProcessAuthentication 이용을 위해 필요
    { 
        if (success) {
            Debug.Log ("Authenticated, checking achievements");
            OpenSavedGame(saveName); //시작하면 최초에 'SavedGame'을 Open 해야 Cloud 기능 이용 가능. saveName을 string으로 지정.            
            // Request loaded achievements, and register a callback for processing them                        
        }
        else
            Debug.Log ("Failed to authenticate");
    }
    

    public void ManualLogin() // 메뉴얼 로그인 버튼. 이미 로그인 돼있으면 안뜸.
    {      
      PlayGamesPlatform.Instance.ManuallyAuthenticate(ManualProcessAuthentication);
    }

    
    internal void ManualProcessAuthentication(SignInStatus status) //메뉴얼 로그인 버튼 이용하기 위한 Authentication을 위해 필요
    {
      if (status == SignInStatus.Success) 
      {
        // Continue with Play Games Services
      } 
      else
      {
        Debug.Log("Not logged in ");
        // Disable your integration with Play Games Services or show a login button
        // to ask users to sign-in. Clicking it should call        
      }
    }    
    
    public void ShowLeaderboard()////전체 리더보드 목록 보여줌, 로그인 안하면 못봄.
    {
        Social.ShowLeaderboardUI(); 
    }    

    
    #region open savedgame
    void OpenSavedGame(string filename) //filename을 우선 Open하여 Cloud를 사용 전에 Device Cache를 사용. 여기선 filename = saveName으로 지정.
    {
        savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.OpenWithAutomaticConflictResolution(filename, DataSource.ReadCacheOrNetwork,    //OpenWithAutomaticConflictResolution은 저장하려는 데이터의 conflict을 방지하기 위함.
            ConflictResolutionStrategy.UseLongestPlaytime, OnSavedGameOpened);                          //conflict 방지 전략으로 UseLongestPlaytime을 이용
    }

    public void OnSavedGameOpened(SavedGameRequestStatus status, ISavedGameMetadata game)  //SavedGame의 Open이 잘 됐는지 체크
    { 
        if (status == SavedGameRequestStatus.Success) {
            Debug.Log("Open Saved Game Success");
            // handle reading or writing of saved game.
        } else {
            Debug.Log("Open Saved Game Failed");
            // handle error
        }
    }
    #endregion

    #region Save to Cloud
    
    public void SaveCloud() //Cloud로 저장을 위해 가져다 쓰면 됨
    {        
        savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.OpenWithAutomaticConflictResolution(saveName, DataSource.ReadCacheOrNetwork,
        ConflictResolutionStrategy.UseLongestPlaytime, SaveGame);
    }

    void SaveGame(SavedGameRequestStatus status, ISavedGameMetadata game) {
        byte[] savedData = ES3.LoadRawBytes("SaveFile.es3"); //Cloud 저장은 byte[]형식을 이용함. ES3.LoadRawBytes를 이용하여 파일 정보를 byte로 가져오면 됨.
        //ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        SavedGameMetadataUpdate.Builder builder = new SavedGameMetadataUpdate.Builder();        
        SavedGameMetadataUpdate updatedMetadata = builder.Build();
        savedGameClient.CommitUpdate(game, updatedMetadata, savedData, OnSavedGameWritten);
    }

    public void OnSavedGameWritten (SavedGameRequestStatus status, ISavedGameMetadata game) //Cloud 저장이 잘 됐는지 체크
    {
        if (status == SavedGameRequestStatus.Success) {
            // handle reading or writing of saved game.
            Debug.Log("Save Cloud Success");
        } else {
            Debug.Log("Save Cloud Failed");
            // handle error
        }
    }
    #endregion    

    #region Load from Cloud
    public void LoadCloud() //Cloud에서 데이터를 가져올 때 쓰면 됨
    {
        savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.OpenWithAutomaticConflictResolution(saveName, DataSource.ReadCacheOrNetwork,
        ConflictResolutionStrategy.UseLongestPlaytime, LoadGameData);        
    }

    void LoadGameData (SavedGameRequestStatus status, ISavedGameMetadata game) {
        savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.ReadBinaryData(game, OnSavedGameDataRead);   
    }
    

    public void OnSavedGameDataRead (SavedGameRequestStatus status, byte[] data) //Cloud 리딩이 잘 됐는지 체크
    {
        if (status == SavedGameRequestStatus.Success) {            
            var loadedData = Encoding.UTF8.GetString(data); //GPGS에서 가져온 data를 loadedData로 넣어줌. Encoding.UTF8.GetString(data)를 이용하여 byte형식의 data를 string으로 변환.
            ES3.SaveRaw(loadedData, "SaveFile.es3");        //string 형태의 loadedData를 SaveFile.es3로 저장.            
            playersetup.gameinitialize();
            upgradepanel.upgradeInitialize();
            normalstagebutton.normalStageInitialize();
            
            Debug.Log("Load Cloud Success");
            // handle processing the byte array data
        } else {
            Debug.Log("Load Cloud Failed");
            // handle error
        }
    }
    #endregion

    #region Delete Cloud data
    public void DeleteCloud()
    {
        DeleteGameData(saveName);
    }

    void DeleteGameData (string filename) {
        // Open the file to get the metadata.
        savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.OpenWithAutomaticConflictResolution(filename, DataSource.ReadCacheOrNetwork,
            ConflictResolutionStrategy.UseLongestPlaytime, DeleteSavedGame);
    }

    public void DeleteSavedGame(SavedGameRequestStatus status, ISavedGameMetadata game) {
        if (status == SavedGameRequestStatus.Success) {
            savedGameClient = PlayGamesPlatform.Instance.SavedGame;
            savedGameClient.Delete(game);
            Debug.Log("Delete Cloud Success");
        } else {
            // handle error
            Debug.Log("Delete Cloud Failed");
        }
    }
    #endregion
}