내일배움캠프 67일차

박나연·2025년 7월 10일

내배캠

목록 보기
60/69

최종 프로젝트 3주차 - 저장 슬롯, 누적시간 저장

오늘의 키워드 : 저장 구현 첫걸음!

<오늘 작업> 2025.07.10

  • SaveSlotData 추가
  • SaveManager.cs 대폭 수정
  • SaveSlotController.cs 작성 : 세이브 슬롯 프리팹에 부착
  • SaveUIManager.cs 작성
  • 게임 시작 버튼 클릭 시 저장 슬롯 세 개 등장 -> 이름 입력

SaveSlot 만들기

일단 monobehavior가 아닌 형식으로 savedata스크립트를 만들어준후

public class SaveSlotData
{
    public string playerName;
    public string saveTime;        // "2025-07-07 13:55" 형태
    public string elapsedTime;     // "123시간 34분 23초" 형태
    public SaveData gameState;     // 실제 게임 상태를 담을 클래스
}

를 넣어주자. 지금 사용하는건 실질적으로 위에 string 세개뿐이다.

using TMPro;
using UnityEngine.SceneManagement;
using UnityEngine;
using UnityEngine.UI;

public class SaveSlotController : MonoBehaviour
{
    [Header("저장 슬롯 인덱스 (0부터)")]
    public int slotIndex;

    [Header("첫 생성용 + 버튼")]
    public Button createButton;
    [Header("로드용 슬롯 버튼")]
    public Button slotButton;
    [Header("삭제용 X 버튼")]
    public Button deleteButton;

    [Header("UI 텍스트")]
    public TextMeshProUGUI nameText;
    public TextMeshProUGUI saveTimeText;
    public TextMeshProUGUI elapsedTimeText;

    void Awake()
    {
        createButton.onClick.AddListener(OnClickCreate);
        slotButton.onClick.AddListener(OnClickLoad);
        deleteButton.onClick.AddListener(OnClickDelete);
    }
    public void Refresh()
    {
        var data = SaveManager.Instance.slots[slotIndex];

        // data가 null이거나, playerName이 비어 있으면 빈 슬롯으로 보기
        bool isEmpty = data == null || string.IsNullOrEmpty(data.playerName);

        createButton.gameObject.SetActive(isEmpty);
        slotButton.gameObject.SetActive(!isEmpty);
        deleteButton.gameObject.SetActive(!isEmpty);

        nameText.gameObject.SetActive(!isEmpty);
        saveTimeText.gameObject.SetActive(!isEmpty);
        elapsedTimeText.gameObject.SetActive(!isEmpty);

        if (!isEmpty)
        {
            nameText.text = data.playerName;
            saveTimeText.text = data.saveTime;
            elapsedTimeText.text = data.elapsedTime;
        }
    }

    // 생성 버튼 눌렀을 때
    private void OnClickCreate()
    {
        SaveUIManager.Instance.OpenNameInput(slotIndex);
    }

    // 로드 버튼 눌렀을 때
    private void OnClickLoad()
    {
        SaveManager.Instance.SelectSlot(slotIndex);
        SceneManager.LoadScene(5);
    }

    // 삭제 버튼 눌렀을 때
    private void OnClickDelete()
    {
        SaveManager.Instance.DeleteSlot(slotIndex);
        Refresh();
    }
}

이건 저장슬롯 프리팹에 붙여준 스크립트이다. 내가 생각한 저장 슬롯 기획은
1. 게임 시작 버튼 클릭
2. +(생성)버튼 클릭(createBtn 활성화/slotBtn, deleteBtn비활성화)
3. 이름 입력 후 확인 버튼 클릭
4. 슬롯 클릭(slotBtn, deleteBtn활성화/createBtn 비활성화)해서 게임 시작
5. x(삭제)버튼 클릭 시 저장 데이터 삭제
6. 다시 +버튼으로 새 저장 가능
이다.

사실 여기서 많이 애를 먹었는데 삭제버튼을 눌러서 데이터를 없앴는데도 +버튼이 활성화가 되지 않는 문제가 있었다. 하드코딩을 하고싶진 않았기에... 시간을 좀 쓴 결과 한줄을 고쳐서 정상작동하게 되었다!
bool isEmpty = data == null || string.IsNullOrEmpty(data.playerName);
원래는 앞부분만 있었는데 string.어찌구를 추가해서 해결하게 되었다. 원래 코드(data == null 만)라면 계속 isEmpty == false 로 판단되어 삭제 후에도 + 버튼이 안 보이고 로드·삭제 버튼만 남는 이상 동작이 발생했었는데
string.IsNullOrEmpty(data.playerName) 를 추가하면서 삭제 직후 (혹은 이름을 입력하지 않은 직후) playerName 이 빈 문자열 상태인 슬롯을isEmpty == true 로 판정해 + 버튼이 보이고, 로드·삭제 버튼은 숨기는 정상적인 UI 전환이 이루어지게 되었다.

SaveManager에서 누적 시간 저장하기

    public void SelectSlot(int idx)
    {
        SelectedIndex = idx;
        sessionStart = DateTime.Now;//플레이 시작 시간 기록
    }
    public void SaveSessionElapsedTime()
    {
        if (SelectedIndex < 0) return;
        var now = DateTime.Now;
        var span = now - sessionStart;
        slots[SelectedIndex].elapsedTime =
            $"누적시간 {(int)span.TotalHours}시간 {span.Minutes}분 {span.Seconds}초";
        SaveAll();
    }

    //게임 종료시 호출해주기(플레이 시간 저장)
    void OnApplicationQuit()
    {
        SaveSessionElapsedTime();
    }
  1. SelectSlot은 플레이어가 저장 슬롯을 고르고 실제 게임씬으로 들어갈 때 호출된다. DateTime.Now를 저장해 이 세션이 언제 시작됐는지를 잡는다.
  2. SaveSessionElapsedTime()는 플레이 시간을 저장한다. span.....은 오늘 처음 써보는 것 같은데 기억해두려 한다!
  3. OnApplicationquit()는 애플리케이션이 완전히 종료될 때 유니티가 자동으로 호출해주는 콜백 메서드이다. 이곳에서 SaveSessionElapsedTime을 호출함으로써 강제 종료하거나 플레이를 중단할때도 누적 시간이 저장된다.

마무리하며

오늘은 첫 모의면접을 진행했는데 팀에서 공개적으로 해서 좀 쪽팔렸다. 그래도 cs질문은 어떤 문제 물어볼거라고 정해주셔서 편했지만.. 미리 준비했는데도 지적을 들어서 쌩으로 면접봤다면 어떻게 됐을지 ㄷㄷ 일단 뭔가를 질문 받고 답변할 때 키워드를 먼저 말해야 한다고 하셨다. ~~는 ~~입니다. 이렇게. 명확한 키워드를 등장시키지 않으면 이걸 잘 알고 있는지에 대한 의심이 든다고 하셨다. 그리고 자기소개는 너무 이력서 축약형처럼 이야기 한다고 지적하셨다. 장단점같은건 말하지 않아도 되며 클라이언트란 키워드를 언급하고, 대학이야기는 말하지 않아도 된다고 하셨다. 그리고 자신의 기술력을 소개하는게 좋을 것 같다고 덧붙이셨다. 참고해서 다음주 자기소개는 더 잘 말해보자.

내일 할 일

내일은 저장기능을 이어서 할것이다. 플레이어 위치, 소지금, 인벤토리를 저장해보려고 하는데 흠... 왠지..어려울 거 같지?만? 일단 해보는거다ㅏㅏㅏㅏ

0개의 댓글