• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    해결됨

퀘스트의 상태인 QuestState를 다른 스크립트에서 받을 수 있나요

24.04.07 01:35 작성 조회수 154

1

이 수업 내용을 토대로 프로젝트에 적용중입니다.

 

구현중인 내용이 퀘스트의 상태에 따라 대화문이 다르게 출력되도록 하고싶은데 대화문을 출력하는 코드에서 퀘스트의 현재 상태를 가져오지 못합니다.

 

이렇게 현재 구현했고 SerializeField 를 통해 불러오고 싶은 스크립터블 오브젝트 Quest를 참조했습니다.

그런데

QuestGetDialogue()

이 코드를 호출했을 때 퀘스트를 받고 난 후에도 Running 상태의 코드를 출력하지 않고

if(quest.State == QuestState.Inactive) { dialogueEvent.dialogues = DataBaseManager.instance.GetDialogue((int)quest.InactiveQuestline.x, (int)quest.InactiveQuestline.y); Debug.Log(quest.State); }

여전히 이 코드를 받아옵니다.

 

Debug.Log 를 통해 확인해봤을 때 Quest System에 등록된 퀘스트는 제대로 상태가 변하는데 이 스크립트에서 변한 상태를 못 받아오는거 같아 질문드립니다. ㅠㅠ

 

답변 2

·

답변을 작성해보세요.

1

수강해주셔서 감사합니다.

먼저 기억하셔야할건 SerializeField로 받아오는건 Quest의 원본이며, QuestSystem에 등록되는건 Quest의 사본입니다.

//QuestSystem.cs 81번줄
public Quest Register(Quest quest)
{
    var newQuest = quest.Clone(); // Quest의 사본
    ...
}

즉, 등록된 Quest의 상태를 찾아오려면 먼저 QuestSystem에 등록된 Quest를 찾아와야합니다.
지금은 그냥 SerializeField로 받은 원본 Quest의 상태를 확인하고 계신데, 원본 Quest는 QuestSystem에 등록되지 않으므로 상태가 계속 Inactive 상태입니다.

함수의 첫 줄에

var registeredQuest = QuestSystem.Instance.ActiveQuests.FirstOrDefault(x => x.CodeName == quest.CodeName);

를 추가하시고, registeredQuest의 상태를 확인하시면 정상 작동할 것으로 보입니다.

감사합니다.

 

Truefalse님의 프로필

Truefalse

질문자

2024.04.07

현재 퀘스트 상태를 확인하려면

Debug.Log(registeredQuest.State);

이렇게 확인 할 수 있는거 맞나요.

늦은 시간에 답변해주셔서 감사합니다.

맞습니다.
다만, 지금 Quest를 ActiveQuests에서 찾아오고 있는데, Quest가 완료되면 CompletedQuests 목록에 들어가게 되므로, Quest가 완료 상태라면 찾아오지 못할겁니다.

그러므로 Quest를 정확히 찾아오기 위해서는 아래와 같이 작성하여야합니다.

var registeredQuest = QuestSystem.Instance.ActiveQuests.FirstOrDefault(x => x.CodeName == quest.CodeName);
// registeredQuest가 null이면 Quest가 실행중이 아니므로, Completed 목록에서 찾아옴.
registeredQuest ??= QuestSystem.Instance.CompletedQuests.FirstOrDefault(x => x.CodeName == quest.CodeName);


위 두 줄을 실행하고 registeredQuest가 여전히 null이라면 Quest가 아직 등록된 적도, 완료된 적도 없는 것입니다.
그러니 if (quest.State == QuestState.Inactive) 이부분을 if (registeredQuest == null)로 바꿔주시면 됩니다.

Truefalse님의 프로필

Truefalse

질문자

2024.04.07

늦은 시간에 답변 주셔서 정말 감사합니다. 해결되었어요!!! 감사합니다.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.04.07

안녕하세요, 인프런 AI 인턴입니다.

질문하신 내용인 다른 스크립트에서 퀘스트의 상태인 QuestState를 받아와서 대화문 출력에 활용하는 경우에 관한 해결책을 찾을 수 있었습니다. (This quest has already been registered).

문제의 핵심은 QuestState가 다른 스크립트에서 업데이트되지만, 해당 변경 사항이 정상적으로 다른 스크립트에 반영되지 않는 상황 같습니다. 이는 Unity에서 스크립트 간의 상태 공유나 참조가 잘못 설정되었을 때 자주 발생하는 문제 중 하나입니다.

해결 방안으로는 다음 두 가지 방법을 제시할 수 있습니다:

  1. 이벤트 리스너 설정: Quest 클래스 내에 상태 변경을 감지하는 이벤트 리스너를 설정하여, 퀘스트의 상태가 변경될 때마다 이벤트를 트리거하는 방식입니다. 이 방법을 사용하면, 다른 스크립트에서 이러한 이벤트를 구독(subscribe)하여 퀘스트 상태에 따른 특정 로직을 실행할 수 있습니다.

  2. 싱글턴 패턴 활용: Quest 관리를 위한 중앙 집중식 매니저(예: QuestManager)를 구현하고, 싱글턴 패턴을 적용하여 언제 어디서나 접근 가능하도록 설정합니다. 이 매니저를 통해 현재 진행 중이거나 활성화된 퀘스트의 상태를 쿼리할 수 있습니다.

주어진 상황에서, 이미 Quest 스크립터블 오브젝트에 대한 참조를 설정하셨기 때문에, 첫 번째 방법인 이벤트 리스너의 설정을 중점적으로 검토해 볼 것을 권장합니다. 이벤트 시스템은 Unity에서 다양한 컴포넌트 간의 상호작용을 관리하는 효율적인 방법 중 하나입니다.

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