基于数据驱动的游戏逻辑有助于减少开发人员的工作量,让开发者可以 直观查看数据的创建和使用流程。这点特别适用于 那些生命周期较长、需要不断根据玩家反馈 调整和平衡数据的游戏。
这类游戏往往需要你将数据导出到 Microsoft Excel 或其他格式的电子表格中,在表格中维护数据, 以及将数据导回游戏。虚幻引擎 的 DataTable 和 CurveTable 允许你将Excel数据导入到引擎中。Excel文档通常是.xlsm(支持宏的Excel文档)格式,其中包含基于宏的导出按钮,支持轻松导出为中间数据格式、逗号分隔的变量(.csv)。
导入引擎后,这些数据表会全部保存在一个位置,以便查找和修改。你可以 右键点击 > 另存为(Save as) 来下载示例.xlsm文件:
数据表
顾名思义,DataTable是一种表格,里面装着大量游戏相关的数据,这些数据会按照其含义和用途分类, 其中,数据字段可以是UObject的任意有效属性(包括资产的引用信息)。设计师若要将 CSV文件导入到DataTable,程序员必须首先创建行容器,以便引擎解释数据。
表格中的列会按照一一对应的关系映射UStruct中的变量,
这些变量必须从 FTableRowBase
继承,才能被导入器识别。第一列的标题应该命名为Name,其中定义了每一行内容的名称。
其它列首先包含一个标题,然后是每一行对应的数据。采用这种
格式后,每一行就反映了一个从 FTableRowBase
继承的UStruct结构的所有数据。
示例
例如,下面是一张经验升级相关的数据表,以及对应的UStruct结构体:
/** 用于定义数据表的结构体 */
USTRUCT(BlueprintType)
struct FLevelUpData : public FTableRowBase
{
GENERATED_USTRUCT_BODY()
public:
FLevelUpData()
: XPtoLvl(0)
, AdditionalHP(0)
{}
/** "Name"一列中的字段表示当前的经验等级 */
/** 升级到下一级所需的经验值 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=LevelUp)
int32 XPtoLvl;
/** 升级后获得生命值加成 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=LevelUp)
int32 AdditionalHP;
/** 升级成就图标 */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=LevelUp)
TSoftObjectPtr<UTexture> AchievementIcon;
};
CSV表格:
Name,XPtoLvl,AdditionalHP,AchievementIcon
1,0,0,"Texture2d'/Game/Textures/AchievementIcon1'"
2,1000,9,"Texture2d'/Game/Textures/AchievementIcon2'"
3,1000,10,"Texture2D'/Game/Textures/AchievementIcon3'"
4,1500,12,"Texture2D'/Game/Textures/AchievementIcon4'"
5,2000,14,"Texture2D'/Game/Textures/AchievementIcon5'"
此处的双引号对于能否正确导入属性很重要。如果不使用双引号,此处导入的内容会变为 Texture2d
。
数据曲线
数据曲线(Data Curves)类似DataTable,区别在于它仅支持浮点类型。与DataTable一样,它的第一列名为"Name", 其中包含各行内容的名称或标题。
其他列的标题相当于曲线的X轴变量,而标题下的数据相当于曲线的Y轴变量。采用这种格式后,每一行都会绘制出一条曲线,开发者甚至可以通过代码获取曲线中的插值数据。
示例
下面是不同等级下的伤害数据:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
Melee_Damage | 15 | 20 | 25 | 30 |
Melee_KnockBack | 1 | 2 | 4 | 8 |
Melee_KnockBackAngle | 10 | 45 | 60 | 65 |
Melee_StunTime | 0 | 1 | 5 | 7 |
导入流程
以下是导入CSV文件的步骤:
- 在Excel或其他电子表格软件中,将你的文件保存为
.csv
格式。 - 打开虚幻编辑器,并点击 内容浏览器(Content Browser) 中的 导入(Import)。
-
选择你想导入为DataTable的CSV文件。你可以 导入为(Import As) 以下类型:
导入为: |
---|
数据表(DataTable) |
曲线表(CurveTable) |
浮点曲线(Float Curve) |
向量曲线(Vector Curve) |
线性颜色曲线(Linear Color Curve) |
-
在下拉列表中选择 DataTable行类型(DataTable Row Type) 。
-
其余 导入选项(Import Options) :
导入选项 | 说明 |
---|---|
忽略额外字段(Ignore Extra fields) | 设置为true可忽略导入数据中的额外字段,如果设置为false,将对此发出警告 |
忽略缺失字段(Ignore Missing Fields) | 设置为true可忽略本该出现但实际缺失的字段,如果设置为false,将对此发出警告 |
导入键字段(Import Key Field) | 导入数据中要用作键的显式字段。如果为空,将对 .JSON 使用Name,并对 .CSV 使用找到的字段 |
-
这会在 内容浏览器(Content Browser) 的当前目录中创建DataTable对象。
-
你可以 双击 对象以在编辑器中查看DataTable的内容。你可以 右键点击 对象并从菜单中选择 重新导入(Reimport) 来更新该对象。 请注意,重新导入对象时将使用原始文件路径。下面是刚导入之后的数据视图:
数据连接
连接这些表格中的数据非常容易。对程序员来说,他们只需 放置一个可在蓝图中暴露的 FDataTableRowHandle 或 FCurveTableRowHandle 变量, 具体取决于你使用的是DataTable还是CurveTable。对于内容提供者来说, 他们会看到一个带有两个子字段的公开字段:
子字段 | 说明 |
---|---|
DataTable/CurveTable | 用于保存数据的表格的引用。 |
RowName | 第一列中的不同数据行的名称/标题。 |
数据用法(仅限C++程序员)
连接数据之后,使用数据非常简单。句柄结构提供了辅助
函数 FindRow()
和 GetCurve()
,可用于检索填充了数据的结构体或曲线。
对于 FCurveTableRowHandle
,将返回 FRichCurve
指针。而 FDataTableRowHandle
则
允许你指定模板函数调用中的结构。该结构可以是最终结构
或继承层级中的任意父结构。
最后需要注意,返回的所有结构和曲线在缓存时都不应超出 函数的本地范围。若表格通过重新导入而刷新,这可以保证数据更改 立即生效,不会访问无效的指针。
在上面的DataTable示例中,引用的资产是延迟加载的资产(TSoftObjectPtr
会处理此情况)。
如果资产字段类型设置为UTexture,每次加载DataTable时都会加载所有资产。