본문 바로가기

내일 배움 캠프/뭐하지

게임 데이터 저장과 로드

[스테이지와 웨이브 정보를 저장 및 복원]

StageInstance 클래스

    ● 현재 플레이 중인 스테이지의 상태(진행 중인 웨이브 포함)를 인스턴스로 표현

        ○ stageKey: 스테이지 번호 (예시: 0, 1, 2...)

        ○ currentWave: 현재 웨이브 인덱스

        ○ currentStageInfo: StageInfo 참조 

    ● 생성자

        ○ 저장할 때 stageKey와 currentWave만 넘기면 되도록 설정

        ○ StageInfo는 런타임에 별도로 세팅

    ● SetStageInfo()

        ○ 외부에서 StageInfo 전체 정보를 할당해 주는 함수

public void SetStageInfo(StageInfo stageInfo)
{
    currentStageInfo = stageInfo;
}

    ● CheckEndOfWave()

        ○ 현재 웨이브가 마지막 웨이브인지 확인

        ○ true: 아직 다음 웨이브가 존재함

        ○ false: 현재가 마지막 웨이브거나 StageInfo가 설정되지 않은 상태

public bool CheckEndOfWave()
{
    if (currentStageInfo == null) return false;
    if (currentWave >= currentStageInfo.waves.Length - 1) return false;
    
    return true;
}

 

StageSaveManager 클래스

    ● StageInstance를 저장/불러오기/삭제하는 유틸리티

    ● JsonUtility를 이용해 JSON 문자열로 변환 후 PlayerPrefs에 저장

    ● SaveKey

        ○ PlayerPrefs에 데이터를 저장할 때 사용할 키 이름

private const string SaveKey = "StageInstance";

    ● 저장 함수 - SaveInstance

        ○ StageInstacne를 JSON 문자열로 변환 

public static void SaveStageInstance(StageInstance instance)
{
    //JSON 문자열로 변환
    string json = JsonUtility.ToJson(instance);
    PlayerPrefs.SetString(SaveKey, json);
    PlayerPrefs.Save();
}

    ● 불러오기 함수 - LoadStageInstance()

        ○ PlayerPrefs에 키 "StageInstance"가 존재하는지 확인

        ○ 존재하면 문자열을 가져와 JSON → 객체로 역직렬화, 없으면 null 반환

public static StageInstance LoadStageInstance()
{
    if (PlayerPrefs.HasKey(SaveKey))
    {
        string json = PlayerPrefs.GetString(SaveKey);
        return JsonUtility.FromJson<StageInstance>(json);
    }

    return null;
}

    ● 저장된 데이터 삭제 - ClearSavedStage()

        ○ PlayerPrefs.DeleteKey(SaveKey)로 해당 키 삭제

        ○ PlayerPrefs.Save()로 즉시 반영

public static void ClearSavedStage()
{
    PlayerPrefs.DeleteKey(SaveKey);
    PlayerPrefs.Save();
}

 


 

[저장/불러오기 흐름]

게임 시작

    ● PlayerPrefs에 저장된 StageInstance가 있다면 불러오고 없으면 새로 생성한다.

    ● StartStage(currentInstance)를 호출하여 게임 진행 시작

private void LoadOrStartNewStage()
{
    StageInstance savedInstance = StageSaveManager.LoadStageInstance();
    if (savedInstance != null)
    {
        currentStageInstance = savedInstance;
    }
    else
    {
        currentStageInstance = new StageInstance(0, 0);
    }
    
    StartStage(currentStageInstance);
}

 

StartStage

    ● 해당 StageInstance에 StageInfo를 할당

    ● 매 스테이지 시작마다 저장 (복구 시 이 지점부터 재개 가능)

public void StartStage(StageInstance stageInstance)
{
    //현재 스테이지 정보 로드 후 해당 스테이지의 현재 웨이브 실행
    StageInfo stageInfo = GetStageInfo(stageInstance.stageKey);
    if (stageInfo == null)
    {
        StageSaveManager.ClearSavedStage();
        currentStageInstance = null;
        return;
    }
    
    stageInstance.SetStageInfo(stageInfo);

    enemyManager.StartStage(currentStageInstance); //몬스터 웨이브
    StageSaveManager.SaveStageInstance(currentStageInstance);
}

 

다음 웨이브 진행

    ● 웨이브 종료 후 다음 웨이브로 전진

    ● 다시 StartStage로 호출 → 진행 사항이 저장됨

public void StartNextWaveInStage()
{
    if(currentStageInstance.CheckEndOfWave())
    {
        //현재 스테이지 내에서 웨이브 인덱스를 증가시켜 다음 웨이브 호출
        currentStageInstance.currentWave++;
        StartStage(currentStageInstance);
    }
    else
    {
        //모든 웨이브 완료 시 스테이지 완료 처리
        CompleteStage();   
    }
}

 

스테이지 완료

    ● 스테이지를 완전히 완료하면 저장을 초기화하고 다음 스테이지로 진입

public void CompleteStage()
{
    StageSaveManager.ClearSavedStage();
    
    if (currentStageInstance == null)
        return;
    
    //다음 스테이지로 전환 및 웨이브 인덱스 초기화
    currentStageInstance.stageKey += 1;
    currentStageInstance.currentWave = 0;
    StartStage(currentStageInstance);
}

 

게임 오버

    ● 저장된 진행 정보 초기화

    ● 이어서 진행 불가능 (처음부터 시작)

public void GameOver()
{
    enemyManager.StopWave();
    StageSaveManager.ClearSavedStage();
}

 

'내일 배움 캠프 > 뭐하지' 카테고리의 다른 글

스탯 시스템 설계  (0) 2025.06.04
오브젝트 풀링  (0) 2025.06.04
스테이지 구조 설계  (0) 2025.06.04
커스텀 에디터  (0) 2025.06.04
Cinemachine  (0) 2025.06.04