본문으로 건너뛰기

퀘스트 시스템

Kill → Talk → Collect 스텝을 조합하는 범용 퀘스트 파이프라인입니다. RPG부터 캐주얼까지 이벤트 기반으로 진행 상황을 추적합니다.

구조

QuestSystem (순수 C# 인스턴스)
— 활성 퀘스트 관리, 이벤트 라우팅

QuestDefinition (ScriptableObject)
— 제목, 설명, 보상 목록
[SerializeReference] List<QuestStep>

QuestInstance (runtime)
— 현재 스텝 인덱스, 완료 상태

QuestStep (abstract, [Serializable])
├── KillQuestStep — 특정 적 N마리 처치
├── TalkQuestStep — 특정 NPC와 대화
└── CollectQuestStep — 특정 아이템 N개 수집

빠른 시작

1. QuestDefinition 에셋 만들기

Create → AchUtils/Quest/Quest Definition

QuestId : "MainQuest_01"
Title : "슬라임 토벌"

Steps:
[0] KillQuestStep
EnemyType : "Slime"
RequiredCount : 5
[1] TalkQuestStep
NpcId : "GuardNPC"
[2] CollectQuestStep
ItemId : "SlimeGel"
RequiredCount : 3

Rewards:
[0] QuestReward { RewardId: "Gold", Amount: 500 }
[1] QuestReward { RewardId: "Exp", Amount: 200 }

2. QuestSystem 인스턴스 만들기

QuestSystem은 상태만 관리하는 순수 C# 클래스입니다. 퀘스트를 소유할 객체에서 직접 생성합니다.

3. 퀘스트 시작

using AchUtils.Quest;

private readonly QuestSystem questSystem = new();

[SerializeField] QuestDefinition mainQuest01;

var instance = questSystem.StartQuest(mainQuest01);

instance.OnStepCompleted += step =>
Debug.Log($"스텝 {step} 완료");

instance.OnQuestCompleted += () =>
GiveRewards(mainQuest01.Rewards);

4. 이벤트 발행

게임 내 어디서든 Progress를 호출합니다. 현재 활성인 모든 퀘스트가 이벤트를 수신합니다.

// 몬스터 사망 시
questSystem.Progress("Kill", "Slime");

// NPC 대화 시
questSystem.Progress("Talk", "GuardNPC");

// 아이템 획득 시
questSystem.Progress("Collect", "SlimeGel");

이벤트 키 규칙

두 번째 인자 (data)스텝
"Kill"적 타입 stringKillQuestStep
"Talk"NPC ID stringTalkQuestStep
"Collect"아이템 ID stringCollectQuestStep

API

QuestSystem

QuestInstance StartQuest(QuestDefinition definition)

void Progress(string eventKey, object data = null)

bool IsCompleted(string questId)
bool IsActive(string questId)
QuestInstance GetActive(string questId)
List<QuestInstance> GetAllActive()

event Action<QuestInstance> OnQuestStarted
event Action<QuestInstance> OnQuestCompleted
event Action<QuestInstance, int> OnQuestStepCompleted

QuestInstance

QuestDefinition Definition
int CurrentStepIndex
bool IsCompleted
QuestStep CurrentStep // 현재 진행 중인 스텝

event Action<int> OnStepCompleted
event Action OnQuestCompleted

커스텀 스텝 만들기

[Serializable]
public class ReachLocationStep : QuestStep
{
public string LocationId;
private bool _reached;

public override bool IsComplete => _reached;

public override void OnProgress(string eventKey, object data)
{
if (eventKey == "ReachLocation" && data is string loc && loc == LocationId)
_reached = true;
}

public override void OnStart() => _reached = false;
}
// 특정 위치 도달 시
questSystem.Progress("ReachLocation", "DungeonEntrance");

중복 시작 방지

같은 QuestId의 퀘스트는 중복 시작되지 않습니다. 이미 완료된 퀘스트도 다시 시작되지 않습니다.

// 두 번 호출해도 인스턴스는 하나
questSystem.StartQuest(mainQuest01);
questSystem.StartQuest(mainQuest01); // 무시됨