- 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.
110 lines
5.0 KiB
C#
110 lines
5.0 KiB
C#
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;
|
||
}
|
||
}
|