강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

파이리님의 프로필 이미지
파이리

작성한 질문수

유니티 시스템 프로그래밍 Pt.1 - 상용 게임 구현을 위한 핵심 시스템 올인원 패키지

챕터 클리어 처리 (InGameManager, ChapterClearUI)

마지막 챕터를 클리어했을때 예외처리 질문입니다.

해결된 질문

작성

·

98

·

수정됨

0

UserPlayData클래스에 MaxClearedChapter 변수가 있습니다.

아래 2군데에서 예외처리가 고민입니다.

  • 로비에 표시하는 챕터정보

  • ChapterClearUI의 earnReward의 조건

     

     

로비의 챕터정보를 표시하려면 MaxClearedChapter를 증가시키면 안될것같고, 그렇다고 그대로 두자니 클리어보상을 매번 받게되어서, MaxClearedChapter를 증가시켜야할것같고...고민입니다.

답변 2

0

BurningCarrot님의 프로필 이미지
BurningCarrot
지식공유자

안녕하세요! BurningCarrot입니다. 문의해 주신 내용에 답변 드립니다.

 

각 챕터의 보상 수령 여부를 별도의 자료구조에 저장하는 것이 좋을 것 같습니다. 예를 들어 RewardEarnedChapter와 같은 Set 자료구조를 추가하고 여기에 보상을 받은 챕터 정보를 추가해 주시고 저장 및 로드하는 코드를 작성해 주시면 될 것 같습니다.

public HashSet<int> RewardEarnedChapter = new HashSet<int>();
//챕터1 보상 수령 시
RewardEarnedChapter.Add(1);

제가 질문의 의도를 정확히 이해하지 못했거나 추가로 궁금하신 점이 있으시다면 편하게 질문 부탁 드립니다. 🙂

파이리님의 프로필 이미지
파이리
질문자

알려주신 코드를 고민해봤지만, 부분적 해결로, 모든고민이 해결되지는 않아서, 다시 질문을 해보겠습니다.

 

제가 이해한 바로는 Ingame씬에서 마지막 챕터를 클리어한다면,

if(m_SelectedChapter > userPlayData.MaxClearedChapter)
{
    userPlayData.MaxClearedChapter++;
    userPlayData.SelectedChapter = userPlayData.MaxClearedChapter + 1;
    userPlayData.SaveData();
}

이와같이 userPlayData에는 SelectedChapter 와 MaxClearedChapter이 각각 1증가 되고, Lobby씬으로 전환이 될것입니다.


Lobby씬에서는 SelectedChapter값에 의해 챕터정보를 가져와 이미지와 텍스트를 세팅하게되는데, 마지막챕터에 1을 더한값은 csv데이터상 유효하지않은 챕터이므로, "CurrChapterData does not exist." 에러가 나올것입니다.

var currChapterData = DataTableManager.Instance.GetChapterData(userPlayData.SelectedChapter);
if(currChapterData == null)
{
    Logger.LogError("CurrChapterData does not exist.");
    return;
}

이를 해결하고 싶습니다.

 

당장의 로비씬 에러를 해결하려고 SelectedChapter를 감소시키기위해, SelectedChapter값이 증감될때 늘 같이 변화되었던 MaxClearedChapter값과 함께 감소시킨다 해도, 챕터클리어 보상조건에서, 감소된 값으로 인해 earnReward 값이 비정상적 값이 대입될것이고, 혼란에 빠졌었습니다.

var uiData = new ChapterClearUIData();
uiData.chapter = m_SelectedChapter;
uiData.earnReward = m_SelectedChapter > userPlayData.MaxClearedChapter;
UIManager.Instance.OpenUI<ChapterClearUI>(uiData);

 

제가 그동안 계속 고민해왔고 지금의 해결방법은,

1 유효한 챕터번호인지 체크후, SelectedChapter에 대입하는 해결방법

if(m_SelectedChapter > userPlayData.MaxClearedChapter)
{
    userPlayData.MaxClearedChapter++;
    if(DataTableManager.Instance.GetChapterData(userPlayData.MaxClearedChapter + 1) != null)
    {
        userPlayData.SelectedChapter = userPlayData.MaxClearedChapter + 1;
    }
    userPlayData.SaveData();
}

2 챕터클리어시, SelectedChapter를 건드리지않는 방법..
마지막챕터클리어시 로비에서 에러는 없겠지만, 다른챕터 클리어시,로비씬에서 해금한 신규챕터를 바로 보여주지못하는 단점이 있습니다.

if(m_SelectedChapter > userPlayData.MaxClearedChapter)
{
    userPlayData.MaxClearedChapter++;
    userPlayData.SaveData();
}

이 2가지 방법이 지금으로선 최선이라고 생각합니다.

에러해결에 집중을 했지만, 좋은코드를 작성하고싶은 욕심에 찝찝한 기분이 들기도 합니다.

불완전한 저의 생각들과 고민의 흔적들을 고려해, 좋은방법을 알려주시면 감사하겠습니다.


마지막챕터: Comming soon 이미지의 바로앞 챕터입니다.

BurningCarrot님의 프로필 이미지
BurningCarrot
지식공유자

안녕하세요! BurningCarrot입니다. 문의해 주신 내용에 답변 드립니다.

질문 내용을 충분히 이해하였고, 첫 번째 방안이 더 적절하다는 것이 제 생각입니다.

DataTableManager에 아래와 같은 함수를 만드신 후,

public int GetMaxChapter()
{
    return ChapterDataTable.Count();
}

아래와 같은 식으로 비교를 하시면 더 가독성을 높일 수 있습니다. 물론 기존 코드 그대로 사용하셔도 상관 없습니다.

if(m_SelectedChapter > userPlayData.MaxClearedChapter)
{
    userPlayData.MaxClearedChapter++;
    if(m_SelectedChapter < DataTableManager.Instance.GetMaxChapter())
    {
        userPlayData.SelectedChapter = userPlayData.MaxClearedChapter + 1;
    }
    userPlayData.SaveData();
}

0

안녕하세요, 인프런 AI 인턴입니다. 쿠쿠팝스님.

질문하신 내용에 대해 고민을 덜어드리기 위해 아래와 같이 설명드리겠습니다.

문제의 이해

  1. MaxClearedChapter: 이 변수는 사용자가 클리어한 마지막 챕터를 의미합니다. 이를 잘못 설정하면 게임 내 로직에 혼란을 초래할 수 있습니다.

  2. 로비의 챕터 정보 표시: 사용자가 클리어한 챕터까지를 보여주되, 다음 챕터로 진행할 수 있는 기능을 제공해야 합니다.

  3. ChapterClearUI의 earnReward 조건: 보상을 중복으로 받지 않도록 운영되어야 합니다.

해결 방안

  1. 클리어한 챕터 정보를 유지:

    • MaxClearedChapter를 활용하여 챕터 정보를 표시하되, 클리어를 확인한 후에 실질적 증가(즉, 최종 저장)는 필요한 시점(예: 일정 챕터 클리어 시)에서 하도록 설계합니다.
  2. 보상 시스템 설계:

    • 보상이 한 번씩만 지급되도록 조건 설정이 필요합니다. 예를 들어, 챕터 클리어 시 IsRewardClaimed처럼 보상을 받았는지를 확인하는 변수를 사용하여, 이 값이 false일 경우에만 보상을 지급하고 true로 업데이트합니다.
  3. 상태 저장 및 복원:

    • 이를 위한 시점과 방법을 명확히 하여 데이터가 유지되도록 설계합니다. 세이브/로드 시스템을 활용하여, 게임 재시작 시에도 값이 유지되도록 합니다.

관련 참조

위 단계들을 통해 문제를 해결할 수 있을 것으로 생각됩니다. 추가적인 이해를 위해 유사한 질문들이 도움이 될 수 있으니 참고해 주시기 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

파이리님의 프로필 이미지
파이리

작성한 질문수

질문하기