내일배움캠프 TIL

내일배움캠프 78일차 TIL "퀘스트 기능"

Jooglorystar 2025. 1. 8. 20:51

 

 

퀘스트는 게임에서 플레이어의 목표가 될 수 있는 요소이다.

 

하지만 단순히 '퀘스트 기능' 이라 했을 때는 어떤 것을 구현해야 하는지 다소 모호한 느낌이 있었다.

그래서 퀘스트 기능을 구현하기 위해 필요한 부분을 정리할 필요가 있다고 느꼈다.

 

퀘스트 기능을 매우 단순하고 러프하게 구분한다면 다음 세가지로 분류할 수 있다고 생각했다.

 

1. 퀘스트 수락

2. 퀘스트 진행

3. 퀘스트 완료

 

1. 퀘스트 수락

 

모든 퀘스트는 퀘스트를 받는 것에서 부터 시작한다. 

우선 퀘스트에 해당 퀘스트를 수락 했는지 판단할 수 있는 값을 넣고 특정 동작을 통해 퀘스트를 수락하거나 취소하는 행위를 구현할 필요가 있다.

 

2. 퀘스트 진행

 

퀘스트에는 목표가 있으며, 그 목표를 수행하는 것이 필요하다. 퀘스트에는 플레이어가 그 목표를 수행하는 것에 대한 감지하는 것이 필요하다.

 

현재 구현하고자 하는 퀘스트 중 하나는 '특정 아이템을 특정 갯수만큼 특정 NPC에게 가져다 주는' 배달 류 퀘스트이다.

이런 퀘스트의 경우, 플레이어가 아이템을 얻거나 소모할 때, 인벤토리를 감지해서 필요한 만큼의 아이템이 있으면 완료 가능 판정, 아니라면 불가 판정을 할 수 있을 것으로 생각된다.

 

3. 퀘스트 완료

 

당연하지만 퀘스트의 마무리는 퀘스트 완료이다.

2번에서 언급한 배달류 퀘스트는 완료 가능 판정이 있을 때, 목표 NPC에게 말을 거는 것이 퀘스트 완료의 행동이 될 수 있을 것이다.

그리고 배달류 퀘스트의 경우 목표 아이템을 정해진 수량만큼 제거하고, 보상을 플레이어에게 지급하는 것이 필요하다.

 

 

 

현재상태

현재 구현한 것은, 퀘스트를 받는 게시판과, 그 게시판에서 퀘스트의 상세정보를 확인하고 수락하는 기능만 구현했다.

 

수락할 퀘스트가 있으면 저렇게 쪽지가 붙어 있다.

 

쪽지를 클릭하면 퀘스트 상세 정보가 뜬다.
수락을 할 경우 수락 게시판에선 사라진다

 

 

구현 세부사항

우선 퀘스트를 관리할 QuestManager에 Quest의 리스트를 만들었다.

Quest 클래스는 추상클래스이며, 상세 퀘스트 종류는 Quest 클래스를 상속해서 구현할 수 있도록 했다.

public abstract class Quest
{
    public int remainDay;
    public EQuestType questType = EQuestType.Default;
    public bool isAccepted;

    private int minRemainDay = 9;
    private int maxRemainDay = 15;

    protected int SetRamainDay()
    {
        return Random.Range(minRemainDay, maxRemainDay);
    }

    public abstract string SetQuestTitle();
    public abstract string SetQuestContent();
    public abstract string SetQuestRemainDay();
    public abstract string SetQuestReward();
}

// 불필요 요소 생략
public class QuestManager : MonoBehaviour
{
    public List<Quest> quests = new List<Quest>();

    private Quest _selectedQuest;
}

 

 

그리고 QuestManager의 quests를 QuestBoardPopup에서 인식하고, Quest의 isAccepted가 false인 퀘스트만 표시되도록 했다.

 

public class QuestBoardPopup : PopupUI
{
    [SerializeField] private QuestPaper[] _papers;
    public QuestInformationPanel questInformationPanel;

    public override void Init()
    {
        base.Init();
    }

    public void Awake()
    {
        _papers = GetComponentsInChildren<QuestPaper>();
    }

    private void OnEnable()
    {
        CheckPapers();
    }

    public void CheckPapers()
    {
        for (int i = 0; i < _papers.Length; i++)
        {
            if (GameManager.Instance.QuestM.quests.Count > i && !GameManager.Instance.QuestM.quests[i].isAccepted)
            {
                _papers[i].SetQuest(GameManager.Instance.QuestM.quests[i], i);
            }
            else
            {
                _papers[i].gameObject.SetActive(false);
            }
        }
    }

    public void OnAcceptButton(bool p_isAccepted)
    {
        if (p_isAccepted)
        {
            Debug.Log("퀘스트 수락");
            GameManager.Instance.QuestM.AcceptQuest();
        }
        questInformationPanel.gameObject.SetActive(false);
        CheckPapers();
    }
}

 

 

아직 구현되지는 않았지만, 수락한 퀘스트를 확인할 수 있는 창에서는 반대로 isAccepted가 true인 퀘스트만 표시되도록 구현할 것이다.

 

 

앞으로의 계획

 

앞으로 더 구현해야하는 부분과 개발할 순서는 다음과 같다.

 

1. 수락한 퀘스트를 확인할 수 있는 창

1-1 해당 창에서 수락한 퀘스트 포기 가능

2. 퀘스트 조건 판단 후 완료 가능, 완료 불가 체크 하기

3. 퀘스트 완료 후 보상 받기