Files
Echo/Assets/_Project/Docs/TaskSystem_Technical_Reference.md
2026-07-08 20:42:51 +08:00

6.7 KiB
Raw Permalink Blame History

TaskSystem 技术参考

本文档定义并说明项目内的“任务系统(TaskSystem)”以及它如何驱动任务面板 UI(TaskPanel)。

相关脚本:

  • Assets/_Project/Scripts/Core/TaskSystem/TaskService.cs
  • Assets/_Project/Scripts/Core/TaskSystem/TaskData.cs
  • Assets/_Project/Scripts/UI/Tasks/TaskPanelController.cs
  • Assets/_Project/Scripts/UI/Tasks/TaskListItemView.cs

相关 UI 搭建与布局参考:

  • Assets/_Project/Docs/TaskSystem_UI_Setup.md

1. 设计目标

  • 任务数据与 UI 解耦:代码不硬编码层级路径,通过 Inspector 槽位绑定 UI。
  • 列表项可做成 Prefab:运行时动态实例化到 ScrollView Content。
  • 任务状态可被外部系统调用修改:支持添加、移除、状态切换(待做/完成/超时)。
  • 超时逻辑由任务系统统一处理:当任务设置了超时时间,自动切换为“超时”状态。

2. 数据模型

2.1 TaskData(任务静态数据)

文件:TaskData.cs

  • 类型:ScriptableObject
  • 字段:
    • id:任务 ID(全局唯一)
    • shortName:短任务名(列表显示)
    • description:任务描述(详情显示)

用途:

  • 设计人员可以在 Project 里创建多个 TaskData 资源,作为“任务定义库”。

2.2 TaskEntry(任务运行时状态)

文件:TaskEntry.cs

  • 运行时由 TaskService 创建与维护
  • 字段:
    • id / data
    • statusTodo | Completed | Expired
    • addedAt:加入时间(秒)
    • expiresAt:过期时间(秒,0 表示不超时)
    • scheduledRemoveAt:计划移除时间(秒,0 表示不自动移除)

3. 任务状态与规则

状态枚举:TaskStatusTaskStatus.cs

  • Todo:待做
  • Completed:完成
  • Expired:超时

规则(当前版本由系统统一规定):

  • 添加任务默认状态为 Todo
  • 当任务设置了 timeoutSeconds > 0
    • 到达 expiresAt 后,系统会自动将状态改为 Expired
  • 任务移除策略:
    • 默认不自动移除(autoRemove...AfterSeconds < 0
    • 可在 TaskService Inspector 中设置:
      • autoRemoveCompletedAfterSeconds
      • autoRemoveExpiredAfterSeconds
    • 当状态切为 Completed/Expired 时,会按配置自动排期移除

时间基准:

  • TaskService.useUnscaledTime = true 时,使用 Time.unscaledTime
  • false 时,使用 Time.time

4. TaskService(系统 API

文件:TaskService.cs

4.1 调用方式

  • 推荐:在外部脚本中通过 Inspector 挂引用(Slot)调用
  • 可选:使用单例 TaskService.Instance(前提是场景里存在一个 TaskService

4.2 公开 API(最常用)

  • 添加(若已存在则失败):
    • bool AddTask(TaskData data, float timeoutSeconds = -1f)
  • 添加或更新(若已存在则更新 data,并可选重置状态):
    • TaskEntry AddOrUpdateTask(TaskData data, float timeoutSeconds = -1f, bool resetStatusToTodo = false)
  • 移除:
    • bool RemoveTask(string taskId)
  • 改状态:
    • bool SetTaskStatus(string taskId, TaskStatus status)
  • 查询:
    • bool TryGetTask(string taskId, out TaskEntry task)
    • IReadOnlyList<TaskEntry> Tasks

4.3 事件(用于驱动 UI

  • Changed:任意任务列表/任务内容变化都会触发
  • 细粒度事件(可按需订阅):
    • TaskAdded
    • TaskUpdated
    • TaskRemoved
    • TaskStatusChanged

5. UI 对接(TaskPanel

5.1 TaskPanelController(面板控制器)

文件:TaskPanelController.cs

它做的事情:

  • 监听 TaskService.Changed,重建列表
  • 实例化 taskItemPrefablistContent
  • 点击列表项时,更新右侧详情文本(titleText/detailText

Inspector 需要绑定的槽位:

  • taskService:场景里的 TaskService
  • listContentScroll View 的 Viewport/Content
  • taskItemPrefab:任务按钮 Prefab(带 TaskListItemView
  • detailText:右侧详情 TMP
  • titleText:可选(右侧标题 TMP

5.2 TaskListItemView(列表项视图)

文件:TaskListItemView.cs

它做的事情:

  • 通过 Reach 的 ButtonManager.SetText() 设置按钮文本
  • 按任务状态设置按钮的 Icon 与颜色(待做/完成/超时)
  • 将按钮 onClick 绑定为“通知 TaskPanelController 选中该任务”

Inspector 需要绑定的槽位:

  • buttonReach 的 ButtonManager(可不填,会在 Awake 尝试自动从同物体 GetComponent
  • todoIcon/completedIcon/expiredIcon:三种状态的 IconSprite

6. 编辑器搭建步骤(从 0 到能跑)

目标场景:

  • Assets/_Project/Scenes/Test/UI_Test.unity

6.1 创建 TaskData 资产

  1. Project 里新建文件夹(建议):Assets/_Project/Data/Tasks
  2. 右键 -> Create -> TaskSystem -> Task Data
  3. 填写:
    • id(例如:task_open_door
    • shortName(例如:打开仓库门
    • description(例如:去工具间找到钥匙,然后打开仓库门。

6.2 制作任务列表项 Prefab(按钮)

  1. UI_Test 场景里,选中你当前用于测试的任务按钮(例如 BtnTaskPrefab
  2. 确认该按钮上存在 Reach 的 ButtonManager 组件
  3. Add ComponentTaskListItemView
  4. (可选但推荐)Add ComponentLayout Element,设置 Preferred Height(例如 56/64),让列表项高度稳定
  5. 将该按钮拖拽到 Project 生成 Prefab(建议放:Assets/_Project/Prefabs/UI/Tasks/TaskListItem.prefab

6.3 在场景中加入 TaskService

  1. Hierarchy 新建空物体:TaskSystem
  2. Add ComponentCore.TaskSystem.TaskService
  3. 配置(可选):
    • Dont Destroy On Load:是否跨场景保留
    • Auto Remove Completed/Expired After Seconds:是否自动移除

6.4 绑定 TaskPanelController

  1. UI_Test 场景中选中 TaskPanelRoot(或你认为最合适的面板根)
  2. Add ComponentUI.Tasks.TaskPanelController
  3. 依次绑定槽位:
    • Task Service -> TaskSystem(TaskService)
    • List Content -> Left_TaskList/Scroll View/Viewport/Content
    • Task Item Prefab -> 第 6.2 步创建的 Prefab
    • Detail Text -> Right_TaskDetails/DetailText
    • Title Text ->(可选)右侧标题 TMP

6.5 (可选)使用 TaskBootstrap 快速验证 UI

  1. TaskSystem 物体上 Add ComponentCore.TaskSystem.TaskBootstrap
  2. Tasks To Add 列表中拖入若干 TaskData
  3. (可选)设置 Timeout Seconds,观察任务在超时后自动变为“超时”

7. 外部系统如何调用(示例)

示例:当玩家触发某个交互后,完成任务:

  • 在你的交互脚本里持有一个 TaskService 引用(Inspector 槽位)
  • 调用:
    • taskService.SetTaskStatus(taskId, TaskStatus.Completed);

示例:添加一个限时任务:

  • taskService.AddTask(taskData, timeoutSeconds: 60f);