メインコンテンツまでスキップ

クエストシステム

クエストシステムは、作成、追跡、進行、完了、失敗、報酬、前提条件、時間制限、繰り返し可能なクエストなど、完全なクエストライフサイクルを提供します。すべてのクエストデータはScriptableObjectを介して定義され、セーブシステムおよびCommandGraphと統合されています。

アーキテクチャ概要​

クラス目的
Questクエストの目標、報酬、前提条件、メタデータを定義するScriptableObject
Objectiveクエスト内の単一の追跡可能なタスクを表すシリアル化可能クラス
QuestReward完了時に付与される報酬を表すシリアル化可能クラス
QuestStatusクエストのランタイム状態:進行カウンター、タイムスタンプ、完了/失敗フラグ
QuestManagerすべてのクエスト状態を追跡し、ライフサイクルを処理し、イベントを発火するSavableObject

Quest​

アセットメニューから MCE > Quests > Quest を選択してクエストを作成します。各 Quest ScriptableObjectには以下のセクションがあります:

分類​

フィールド型説明
IsMainQuestboolメインクエストはストーリー進行に重要
CategoryQuestCategoryクエストログ内でクエストを整理(下記参照)
DifficultyQuestDifficultyEasy、Normal、Hard、Expert — UIに表示

クエストカテゴリ:

  • MainStory — メインストーリー進行
  • SideQuest — オプションのNPCクエスト
  • DailyTask — 24時間ごとにリセット
  • WeeklyChallenge — 7日ごとにリセット
  • Event — 期間限定イベントクエスト
  • Collection — MonsterDEXを埋める、すべてのアイテムを見つけるなど

クエスト提供者​

フィールド型説明
QuestGiverCharacterDataこのクエストを割り当てるNPC

必要条件​

フィールド型説明
PrerequisiteQuestsList<Quest>最初に完了しなければならないクエスト
MinBadgesint受け入れるための最小バッジ数(0 = なし)
RecommendedLevelintUIに表示されるが、強制はされない

時間と繰り返し​

フィールド型説明
TimeLimitSecondsint秒単位の時間制限(0 = 制限なし)。期限切れでクエストは自動失敗
IsRepeatablebool完了後にクエストを再開できるか
RepeatCooldownSecondsint再受け入れ前のクールダウン(86400 = 毎日、604800 = 毎週)

Objective​

各クエストには、プレイヤーが完了しなければならないタスクを定義する List<Objective> が含まれています。目標は順序付けられており、自動的に進行できます。

目標タイプ(11種類)​

タイプ説明主要フィールド
Talk特定のNPCと話すTargetNPC
DeliverNPCにアイテムを届けるTargetNPC、TargetItem
Defeatトレーナーまたは野生のモンスターを倒すTargetMonster(null = 任意)、TargetCount
Catch特定の種を捕まえるTargetMonster、TargetCount
Collectアイテムを一定数収集するTargetItem、TargetCount
GoTo特定のマップに移動するMapLocation
EscortNPCを目的地まで護衛するTargetNPC、MapLocation
Evolveある種のモンスターを進化させるTargetMonster
HatchEggモンスターのタマゴを孵化させるTargetMonster(null = 任意)
WinAtFacility特定の施設でバトルに勝利するMapLocation
Customゲーム変数で追跡CustomVariableKey、TargetCount

目標フィールド​

[Serializable]
public class Objective
{
public string LocalizationKey; // ローカライズされた説明テキスト
public ObjectiveType Type; // プレイヤーがすべきこと
public SceneInfoAsset MapLocation; // 場所(GoTo用、ミニマップマーカー)
public CharacterData TargetNPC; // 誰(Talk/Deliver/Escort用)
public MonsterEntry TargetMonster; // どの種(null = 任意)
public ScriptableObject TargetItem; // どのアイテム(Collect/Deliver用)
public int TargetCount = 1; // 必要な数
public bool IsOptional; // ボーナス目標、必須ではない
public bool HiddenUntilPrevious; // 前の目標が完了するまで非表示
public string CustomVariableKey; // カスタムタイプ追跡用
}

オプションの目標はクエスト完了をブロックしません。隠し目標は、クエストが進行するにつれて発見の感覚を生み出します。

QuestReward​

各クエストには、完了時に自動的に付与される List<QuestReward> があります。

報酬タイプ(6種類)​

タイプフィールド例
ItemItemReward、ItemQuantity5x スーポーション
MoneyMoneyAmount$5,000
ExperienceExpAmount2,000 EXPをパーティに分配
MonsterMonsterReward、MonsterLevelLv.20 サンダーメイン
GameVariableGameVariableKey、GameVariableValueHAS_BIKE = 1 を設定
UnlockCustomUnlockId"safari_zone_access"
// 各報酬にはUI用の人間が読める説明がある
reward.GetDescription(); // "スーポーション x5"、"$5,000"、"2,000 EXP"など

QuestManager​

QuestManager は、すべてのクエストランタイム状態を所有する SavableObject(セーブ/ロード対応のScriptableObject)です。MCE > Quests > Manager で作成します。

クエストライフサイクル​

未開始  -->  StartQuest()  -->  アクティブ(目標追跡中)
|
+---------+-----+-----+---------+
| |
CompleteQuest() FailQuest()
| |
完了 失敗
|
(IsRepeatableの場合)
|
StartQuest()(クールダウン後)

クエストの開始​

questManager.StartQuest(quest, startingObjective: 0);

これにより QuestStatus エントリが作成され、開始タイムスタンプが記録され、通知が表示され、初期目標が設定されます。クエストが繰り返し可能でクールダウン中の場合は、警告とともに呼び出しが無視されます。

目標の進行​

// 目標 #0 の進行カウンターを1増やす
questManager.UpdateObjectiveProgress(quest, objectiveIndex: 0, delta: 1);

進行が目標の TargetCount に達すると、システムは通知を表示し、自動的に次の非オプション目標に進みます。すべての必須目標が完了すると、クエストは自動的に完了します。

現在の目標を直接設定することもできます:

questManager.SetQuestObjective(quest, objective: 2);

完了と失敗​

questManager.CompleteQuest(quest);  // 完了としてマーク、報酬を付与、イベントを発火
questManager.FailQuest(quest); // 失敗としてマーク、イベントを発火

時間制限クエスト​

questManager.CheckTimeExpiry() を定期的に(例:MonoBehaviourのUpdateから)呼び出して、期限切れのクエストを自動的に失敗させます:

long remaining = questManager.GetRemainingTime(quest); // 秒、または -1

クエストの照会​

// プレイヤーが操作したすべてのクエスト
Dictionary<Quest, QuestStatus> all = questManager.GetAllQuests();

// フィルターされたクエリ
List<Quest> active = questManager.GetActiveQuests();
List<Quest> completed = questManager.GetCompletedQuests();
List<Quest> failed = questManager.GetFailedQuests();

// カテゴリ、完了状態、失敗状態でフィルター
// シグネチャ:GetQuestsFiltered(QuestCategory? category = null, bool? completed = null, bool? failed = null)
List<Quest> dailies = questManager.GetQuestsFiltered(
category: QuestCategory.DailyTask,
completed: false,
failed: null
);

// 前提条件を確認
bool canStart = questManager.ArePrerequisitesMet(quest);

// 開始可能なすべてのクエストを取得(前提条件満たしている、まだ開始していない)
List<Quest> available = questManager.GetAvailableQuests();

// プレイヤーが特定のクエストを持っているか確認
bool has = questManager.HasQuest(quest);

ゲーム完了率​

QuestManager は完了したクエストに基づいてゲーム完了率を追跡します。自動計算(完了 / ワールドデータベース内の全クエスト数)または固定の分母(QuestsForHundo)に対して計算できます。VisibleGamePercentage が true に設定されると、パーセンテージがプレイヤーに表示されます。

float pct = questManager.GameCompletionPercentage; // 0.0 - 1.0

イベント​

questManager.OnQuestStarted      += (Quest q) => { ... };
questManager.OnObjectiveProgressed += (Quest q, int objIdx, int newVal) => { ... };
questManager.OnObjectiveChanged += (Quest q, int newObjIdx) => { ... };
questManager.OnQuestCompleted += (Quest q) => { ... };
questManager.OnQuestFailed += (Quest q) => { ... };
questManager.OnRewardsGranted += (Quest q, List<QuestReward> rewards) => { ... };

セーブ / ロード​

QuestManager は SavableObject を拡張し、SavableQuestManager を介してすべてのクエスト状態をJSONにシリアル化します。クエスト参照は名前で保存され、ロード時に WorldDatabase に対して解決されます。

CommandGraphノード(10個)​

クエストシステムは、NPCスクリプトやイベントトリガーで使用するための10個のCommandGraphノードを提供します:

アクションノード​

ノード説明
StartQuestオプションの初期目標インデックスでクエストを開始
CompleteQuestクエストを完了としてマーク(報酬を付与)
FailQuestクエストを失敗としてマーク
UpdateQuestObjective現在の目標を特定のインデックスに設定
ProgressQuestObjective目標の進行カウンターをデルタ分増加
UnlockGameCompletionPercentage完了率をプレイヤーに表示可能にする

条件ノード​

ノード説明
IfPlayerHasQuestプレイヤーがクエストを開始(または完了)した場合に分岐
IfCompletedQuestクエストが完了した場合に分岐
IfQuestFailedクエストが失敗した場合に分岐
IfCurrentQuestObjectiveクエストの現在の目標が特定のインデックスと一致する場合に分岐

例:NPCクエストフロー​

[IfPlayerHasQuest] -- いいえ --> [Dialog: "助けが必要だ!"] --> [StartQuest]
-- はい --> [IfCompletedQuest] -- はい --> [Dialog: "ありがとう!"]
-- いいえ --> [IfCurrentQuestObjective(1)]
-- はい --> [Dialog: "見つけたか?"]
-- いいえ --> [Dialog: "探し続けろ!"]

クエストの作成:ステップバイステップ​

  1. Questアセットを作成:プロジェクトウィンドウで右クリックし、MCE > Quests > Quest を選択
  2. 分類を設定:カテゴリ、難易度、メインクエストかどうかを選択
  3. クエスト提供者を割り当て:NPCの CharacterData をQuest Giverフィールドにドラッグ
  4. 目標を定義:Objectivesリストにエントリを追加。各目標のタイプ、ターゲット、数を設定
  5. 報酬を定義:Rewardsリストにエントリを追加。報酬タイプを選択し、関連フィールドを記入
  6. 前提条件を設定(オプション):他のQuestアセットをPrerequisiteQuestsにドラッグ
  7. 時間/繰り返しを設定(オプション):TimeLimitSeconds や IsRepeatable とクールダウンを設定
  8. WorldDatabaseに登録:クエストを WorldDatabase.Quests に追加して、可用性クエリに表示されるようにする
  9. CommandGraphを配線:NPCのCommandGraphでクエストノードを使用して、クエストを開始、追跡、完了する