본문 바로가기
스파르타 내배캠

스파르타 내배캠 Unity 3기 - 55

by LemongO 2024. 4. 10.

 

 

Save & Load

 

아직 구현되지 않은 부분이 많긴 하지만

기본적으로 게임을 실행 할 때마다 파츠가 초기화 된다면 조금 불편할 것 같다.

 

그래서 저장할 데이터는 많아도 먼저 파츠 정보를 저장하고 불러오는 로직을 짜 보았다.

 

[Serializable]
public class GameData
{    
    public int highestLevel;

    public int achievementCoin;

    public int partIndex_Lower;
    public int partIndex_Upper;
    public int partIndex_LeftArm;
    public int partIndex_RightArm;
    public int partIndex_LeftShoulder;
    public int partIndex_RightShoulder;

    public List<int> unlockedPartsList = new List<int>();
}

먼저 저장할 데이터를 보관하는 GameData  클래스.

 

플레이어의 모듈에 쓰이는 파츠는

하체 / 상체 / 왼팔 / 오른팔 / 왼어깨 / 오른어깨

총 6가지이고 각각 파츠 리스트의 Index 파츠를 사용하기 때문에 int 를 사용한다.

 

public class GameManager
{
    public GameData gameData = new GameData();

    private string _filePath;

    public void Init()
    {
        _filePath = Path.Combine(Application.dataPath, "GameData.json");

        if (File.Exists(_filePath))
            gameData = LoadGame();
    }
    
    public void SaveGame()
    {
        string json = JsonUtility.ToJson(gameData, true);

        File.WriteAllText(_filePath, json);
        Debug.Log("Game Data Saved");
    }

    public GameData LoadGame()
    {
        string json = File.ReadAllText(_filePath);

        GameData loadedGameData = JsonUtility.FromJson<GameData>(json);
        return loadedGameData;
    }
}

GameManager 싱글톤 클래스에서 (Managers 클래스에서 관리되는)

GameData 정보를 가지고 있게한다.

 

게임이 실행되면 최초로 Managers에 의해 Init 함수가 호출이 되고

GameData 를 생성, 로드 할 수 있는 정보가 있다면 로드하여 할당한다.

 

그리고 GameManager 내부에 GameData의 PartIndex 를 프로퍼티로 만들어

get 시 data의 Index를

set 시 data의 Index = value로 그리고 SaveGame을 실행한다.

 

// ### GameManager.cs 
 
 #region Parts Index
    public int PartIndex_Lower { 
        get => gameData.partIndex_Lower; 
        set
        {
            gameData.partIndex_Lower = value;
            SaveGame();
        }
    }
    public int PartIndex_Upper
    {
        get => gameData.partIndex_Upper;
        set
        {
            gameData.partIndex_Upper = value;
            SaveGame();
        }
    }
    // 중략...    
    #endregion

 

UI 교체 버튼을 클릭하면 ModuleManager의 ChangePart 메서드가 실행된다.

이 때 UI가 가지고있는 자신의 Index를 매개변수로 넘겨받아 GameManager의 PartIndex_OO = index로 할당한다.

// ### ModuleManager.cs

public void ChangePart(int index, Parts_Location partsType)
{
    switch (partsType)
    {
        case Parts_Location.Lower:
            if (_gameManager.PartIndex_Lower == index) return;

            CurrentUpperPart.transform.SetParent(CurrentModule.transform); // 상체 부모 오브젝트 변경
            UnityEngine.Object.DestroyImmediate(CurrentLowerPart.gameObject); // 즉시 파괴

            CurrentLowerPart = CreatePart<LowerPart>(partsType, CurrentModule.LowerPosition, index); // 하체 생성
            _gameManager.PartIndex_Lower = index;

            CurrentUpperPart.transform.SetParent(CurrentLowerPart.UpperPositions); // 상체 부모 오브젝트 변경
            CurrentUpperPart.transform.localPosition = Vector3.zero; // 상체 위치 조정
            break;
        
        // 중략...
    }
}

 

이렇게 PartIndex를 할당하면 프로퍼티의 setter에 의해 알아서 저장이 되도록 만들었다.