AchievementSystem 2.0

适用于 Unreal Engine 的模块化、灵活的成就系统。提供用于管理成就和分类的简洁核心,不强制任何 UI 或存档逻辑。


简介

AchievementSystem 提供了一个用于管理成就和分类的简洁核心。它不强制使用任何 UI 或存档逻辑,因此您可以完全自主控制。所有数据均从数据表(Data Table)加载,便于本地化并可高效扩展。

数据表驱动名称、描述和图标都存放在数据表中,可直接用于本地化。
两级分类顶级分类包含分类,分类包含成就。
进度追踪每个成就都有当前进度和最大进度,并支持自动完成。
UI 就绪的数据结构化的只读函数,可直接接入控件(Widget)。
支持多人游戏为在线游戏和多档案游戏提供按玩家区分的系统引用。
额外的宏包含 For Each With Delay 和 Get All Data Table Items。

系统工作原理

系统围绕一个简单的数据流构建。

  1. 定义
    成就和分类在数据表中定义,并在运行时预加载。
  2. 保存与加载
    由您控制成就的保存和加载方式,然后告知系统哪些成就已经解锁。
  3. 使用
    加载完成后,系统会按分类组织成就,并提供结构化数据,您可以直接用于 UI 或游戏逻辑。

快速入门

  1. 创建子蓝图
    打开 BP_AchievementsSystem,创建一个子蓝图类(Child Blueprint Class)。该子蓝图将作为您的主成就系统实例。
  2. 创建结构体
    创建一个包含成就数据的结构体(Structure)。必须包含 ID(整数)和 Max Progress(整数)。
  3. 创建数据表
    创建一个数据表,并将其指定为您创建的结构体。填入成就数据(名称、描述、图标等)。
  4. 打开事件图表
    打开 BP_Achievements_Child,进入事件图表(Event Graph)。
  5. 添加 Preload Achievement Data
    添加函数 Preload Achievement Data。它需要三个值(见下表)。
  6. 连接各个值
    为每个要预加载的成就连接所有必需的值。
输入描述
ID成就的唯一标识符。
Max Progress完成成就所需的最大进度值。
Row Name该成就在数据表中的行名称。
需要示例?请参考演示 AchievementStyle_01。

分类概览

分类系统是一个仅有两级的简单树形结构:顶级分类(Top Level Categories)和成就分类(Achievement Categories)。这使系统易于理解且高效。

顶级分类 01
├─ 分类 01
│   ├─ 成就
│   └─ 成就
└─ 分类 02
    ├─ 成就
    └─ 成就

预加载成就分类

要定义哪些成就属于某个分类,请使用 Preload Achievement Category。其工作方式与预加载成就相同。

输入描述
Category ID分类的唯一标识符。
Achievement IDs(Array)属于该分类的所有成就 ID。
Row Name该分类在分类数据表中的行名称。

预加载顶级分类

顶级分类用于将多个分类归为一组。请使用 Preload Top Level Category。

输入描述
Category ID顶级分类的唯一标识符。
Category IDs(Array)属于该顶级分类的所有分类 ID。
Row Name该顶级分类在数据表中的行名称。

简单示例

进度(顶级分类 01)
├─ 剧情(分类 01)
│   ├─ 第一步
│   └─ 全新的开始
└─ 探索(分类 02)
    ├─ 初次发现
    └─ 探索大师

技能(顶级分类 02)
├─ 通用技能(分类 01)
│   └─ 完美执行
└─ 精准(分类 02)
    ├─ 一击制胜
    └─ 稳健之手

函数参考

注意:这些函数均为只读,不会修改任何数据(Achievement Trigger 除外)。

已完成成就(Complete Achievements)

以下三个函数返回相同的结构体:

函数输入描述
Get All Completed Achievements无系统中所有成就的整体进度。可用于统计、UI 或玩家反馈。
Get All Completed Achievements By CategoryCategory ID指定分类内的进度。可用于显示分类进度 UI,或检查某个分类是否已全部完成。
Get Completed Achievements In Top Level CategoryCategory ID(顶级分类)顶级分类内(包括其所有子分类)的进度。可用于显示一组分类的进度。

加载(Load)

成就加载函数返回一个结构体数组,包含:Row Name、Complete Date(String)、Progress(Int)、Max Progress(Int)和 Is Completed(Bool)。

函数输入输出 / 用途
Load Achievements By CategoryCategory ID某个分类内的所有成就。用于填充单个分类的 UI。
Load All Achievements无一次性获取所有成就。用于整体统计或游戏结束时的汇总。
Load All Categories无包含 ID 和 Row 的结构体数组。用于填充分类列表或执行分类级操作。
Load Child CategoriesCategory ID(父级 / 顶级)每个子分类的 ID 和 Row。用于在顶级分类内显示子分类。
Load Top Level Categories无包含 Row、Category ID 和 Category IDs(子分类数组)的结构体数组。用于显示所有顶级分类及其子分类。

状态(States)

这三个都是纯函数(Pure Function)。

函数输入输出用途
Get ProgressAchievement ID (Int)Progress (Int)、Max Progress (Int)显示或检查单个成就的进度。
Get Row NameAchievement ID (Int)Row Name (Name)获取某个成就的本地化数据(名称、描述、图标)。
Is Completed ?Achievement ID (Int)Return Value (Bool)检查成就的完成状态,用于游戏逻辑或 UI 更新。

Achievement Trigger

为指定玩家触发并更新某个成就的进度。

输入描述
Achievement ID (Int)要触发的成就 ID。
Player Ref (Actor)触发该成就的玩家引用。

用途:每当玩家执行与成就相关的操作(击杀、收集、探索、交互等)时调用。

Get Achievement Data

查找默认的成就系统实例并返回其引用。

Get Achievement Data By Reference

返回与特定玩家关联的成就系统,使每个玩家都能拥有自己的成就数据。

重要的架构说明

本系统中除 Achievement Trigger 之外的所有函数,其内部都构建于 Get Achievement Data 之上。这意味着它们:

多人 / 在线游戏须知

如果您正在开发在线或多人游戏,请勿将这些函数用于游戏逻辑。仅在 UI 中使用它们,用于显示进度、已完成成就和分类。

要使用特定玩家的成就系统引用:

  1. 前往 BP_AchievementFunctions。
  2. 找到您想使用的函数。
  3. 复制(Duplicate)该函数。
  4. 修改新函数,使其使用 Get Achievement Data By Reference。
  5. 为该函数添加 Player Reference 输入。

这样您就能完全掌控按玩家区分的成就数据,以及对多人游戏安全的逻辑。

为什么 Achievement Trigger 不同

Achievement Trigger 不依赖 Get Achievement Data。它需要成就 ID 和玩家引用,因此可安全用于游戏逻辑、支持多人游戏,并由开发者完全掌控。

无玩家地图说明

在没有玩家(Player)或角色(Character)的关卡中,成就系统默认无法工作。要解决此问题,请将 BP_AchievementsWorld 添加到您的关卡并配置其属性:

属性描述
Achievement Class选择您要使用的成就组件(例如 BP_AchievementStyle_01)。
EAchievement Date Format完成日期的日期格式(例如 USA,MM/DD/YYYY)。
Use Category Optimized Loading启用按分类优化加载。
Auto Load Category启用分类自动加载。

这样系统就能在主菜单、登录界面或其他无玩家的地图中正常运行。

附加工具

For Each With Delay (Macro)

与普通的 For Each Loop 相同,但在每次迭代之间增加延迟。

引脚描述
Array要遍历的数组。
Duration (Float)处理每个元素之间的时间间隔(默认 0.05)。
Loop Body、Array Element、Array Index、Completed行为与标准 For Each Loop 相同。

适用于按顺序加载 UI 元素、成就或任何数组数据,而不会造成游戏卡顿。

Get All Data Table Items (Macro)

无需编写多个节点,即可获取数据表中的所有行。

引脚描述
Table (input)您要读取的数据表(Data Table)。
Loop Body对每一行执行。Array Element / Out Row 是当前项的行结构体。
Row Not Found当行不存在时触发。
Completed所有行处理完毕后触发。

适用于以简洁高效的方式快速遍历数据表。