Files
zeling_v2/Assets/_Game/Scripts/Quest/QuestObjectiveSO.cs
Joywayer 446fd5dcd0 feat: Add WorldStateFlagAttribute and custom property drawer for enhanced dialogue management
- Implemented WorldStateFlagAttribute to mark string fields as world state flags.
- Created NarrativeNPCEditor for custom inspector to visualize dialogue version activation states.
- Developed WorldStateFlagDrawer to provide dropdown menu for known flags in the inspector.
- Introduced ActorModule for managing DialogueActorSO assets, including viewing, creating, and deleting actors.
- Added DialogueModule for managing DialogueSequenceSO assets with detailed previews and action bars.
- Established QuestModule for managing QuestSO assets, including objectives and branches.
- Implemented QuestManagerPostprocessor to automatically refresh QuestManager's quest list on asset changes.
2026-05-24 00:36:11 +08:00

110 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using BaseGames.Player;
namespace BaseGames.Quest
{
/// <summary>
/// 任务目标基类(抽象,架构 22_QuestChallengeModule §3
/// 所有具体目标类型均继承此类,通过多态实现零代码扩展。
/// 每种目标在事件驱动下由 QuestManager 调用 EvaluateCompletion()。
/// </summary>
public abstract class QuestObjectiveSO : ScriptableObject
{
[Header("标识")]
[Tooltip("目标唯一 ID如 \"OBJ_TalkElder\"。空时由 OnValidate 自动以资产名填充。")]
public string objectiveId;
[Tooltip("本地化 Key格式如 \"Quest_FindMushroom_Obj1\"。通过 LocalizationManager.Get(displayTextKey, \"Quest\") 显示给玩家。")]
[TextArea(1, 4)]
public string displayTextKey;
[Tooltip("勾选后此目标为可选项:完成可获奖励,但不阻塞任务交接。")]
public bool IsOptional;
/// <summary>根据当前进度判断目标是否完成。</summary>
public abstract bool EvaluateCompletion(QuestObjectiveState state);
/// <summary>
/// 在 DataHub / 编辑器工具中显示的类型徽章文字。
/// 子类应 override 返回简洁中文标签(如 "[对话]")。
/// 避免工具代码中使用 type-switch 维护列表。
/// </summary>
public virtual string BadgeLabel => "[目标]";
#if UNITY_EDITOR
private void OnValidate()
{
if (!string.IsNullOrEmpty(objectiveId)) return;
objectiveId = name;
UnityEditor.EditorUtility.SetDirty(this);
}
#endif
}
// ── 运行时目标进度状态(由 QuestManager 管理,不继承 SO────────────────
public class QuestObjectiveState
{
public bool completed = false;
public int progressCount = 0;
}
// ── 具体目标类型 ────────────────────────────────────────────────────────
/// <summary>与指定 NPC 对话后完成。</summary>
[CreateAssetMenu(menuName = "BaseGames/Quest/Objective/TalkToNPC")]
public class TalkToNPCObjective : QuestObjectiveSO
{
[Tooltip("目标 NPC 的唯一 ID需与 NPC 组件上的 npcId / InteractableNPC.npcId 保持一致。")]
public string targetNpcId;
public override string BadgeLabel => "[对话]";
public override bool EvaluateCompletion(QuestObjectiveState s) => s.progressCount >= 1;
}
/// <summary>击败指定 ID 的敌人若干次。</summary>
[CreateAssetMenu(menuName = "BaseGames/Quest/Objective/Defeat")]
public class DefeatEnemyObjective : QuestObjectiveSO
{
[Tooltip("目标敌人的唯一 ID需与敌人 SO 或敌人组件上的 enemyId 保持一致。")]
public string targetEnemyId;
[Tooltip("需击败的次数,默认 1。")]
[Min(1)] public int defeatCount = 1;
public override string BadgeLabel => "[击败]";
public override bool EvaluateCompletion(QuestObjectiveState s) => s.progressCount >= defeatCount;
}
/// <summary>收集指定 ID 的物品若干件。</summary>
[CreateAssetMenu(menuName = "BaseGames/Quest/Objective/Collect")]
public class CollectItemObjective : QuestObjectiveSO
{
[Tooltip("目标物品的唯一 ID需与拾取事件广播的 itemId 保持一致。")]
public string itemId;
[Tooltip("需收集的数量,默认 1。")]
[Min(1)] public int collectCount = 1;
public override string BadgeLabel => "[收集]";
public override bool EvaluateCompletion(QuestObjectiveState s) => s.progressCount >= collectCount;
}
/// <summary>到达指定场景/区域标记点后完成。</summary>
[CreateAssetMenu(menuName = "BaseGames/Quest/Objective/Reach")]
public class ReachAreaObjective : QuestObjectiveSO
{
[Tooltip("需到达的场景名Unity Build Settings 中的场景名称)。")]
public string sceneName;
[Tooltip("场景内的目标标记 Tag预留字段当前未启用。")]
public string markerTag;
public override string BadgeLabel => "[到达]";
public override bool EvaluateCompletion(QuestObjectiveState s) => s.progressCount >= 1;
}
/// <summary>使用指定能力若干次后完成。</summary>
[CreateAssetMenu(menuName = "BaseGames/Quest/Objective/UseSkill")]
public class UseSkillObjective : QuestObjectiveSO
{
[Tooltip("目标能力类型。事件频道 EVT_SkillUsed 广播 AbilityType.ToString(),与此值匹配时计数。")]
public AbilityType requiredAbility;
[Tooltip("需使用的次数,默认 1。")]
[Min(1)] public int useCount = 1;
public override string BadgeLabel => "[使用]";
public override bool EvaluateCompletion(QuestObjectiveState s) => s.progressCount >= useCount;
}
}