正文
剖析某些大型游戏的框架,可以发现广泛运用了 DataTable
与 DataAsset
来管理数据,DataTable
的导入直接用 Excel 就能很轻易的完成,但是 DataAsset
却要一直手动去填,当 DataAsset
有几百个时,哪怕通过引擎自带的 Bulk Edit 去调也是一个噩梦。
那么假如可以将 DataTable
与 DataAsset
结合起来去填充 DataAsset
的数据,那么不香么?
结合了钊哥的数据驱动教程
提供的将 DataTable
在编辑器中编辑的思路,我简易地实现了这个非常方便的功能。想直接看效果的可以看我的这个视频
UE4 C++结合DataTable批量快速创建DataAsset
现在简要地说明一下实现流程
在阅读本文之前,假设你已经对 DataTable
和 DataAsset
已经有了初步的了解。
为了简单起见,本文不结合 AssetManager
在 DataAsset
中应用 FPrimaryAssetType
这个概念,读者有需要可以自行补充。
- 在 C++ 中创建以
FTableRowBase
为父类的结构体FItemsProperties
其余属性,读者自行填充
- 以该结构体为基准,在 Excel 中填好数据,并将 csv 文件导入虚幻4,生成
DataTable
。(这一步的具体实现请参考官方文档有关教程
导入完成后在 UE4 中如下图所示
打开为
- 在 C++ 中以
UPrimaryDataAsset
为父类创建自定义的DataAsset
,其中ItemProperty
是刚才创建的DataTable
结构体FItemsProperties
。
/** Base class for all items*/
UCLASS(BlueprintType)
class MYGAME_API UItemBase : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
/*ItemProperty*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Item)
FItemsProperties ItemProperty;
};
- 在 C++ 中以
UBlueprintFunctionLibrary
为父类创建蓝图函数库
并创建 CreateNewDataAsset
函数
.h 如下
UCLASS(Blueprintable, Category = "DataDriven")
class MYGAME_API UMyDataFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
#if WITH_EDITOR
/*Create NewDataAsset in the Editor.The PackagePath cannot end with /.*/
UFUNCTION(BlueprintCallable, Category = "Editor Scripting | DataAsset")
static void CreateNewDataAsset(const FString PackagePath, const FString AssetName, const FItemsProperties& ItemProperty);
#endif
};
在 cpp 文件中的具体实现为(没错,就是标准的创建 Asset 的流程,注意必要时需要对 DataTable
结构体中的拷贝赋值运算符进行重载,防止浅拷贝)
.cpp 如下
void UMyDataFunctionLibrary::CreateNewDataAsset(const FString PackagePath, const FString AssetName,const FItemsProperties& ItemProperty)
{
// 创建 package
UPackage* MyPackage = CreatePackage(nullptr, *PackagePath);
// 创建 Object
UItemBase* ItemDataAsset = NewObject<UItemBase>(MyPackage, UItemBase::StaticClass(), *AssetName, EObjectFlags::RF_Public | RF_Standalone);
if (ItemDataAsset == nullptr)
{
return;
}
// 初始化对象 ==
ItemDataAsset->ItemProperty = ItemProperty;// 简要起见,直接赋值,必要时需要对拷贝赋值运算符重载
// 结束初始化对象 ==
FAssetRegistryModule::AssetCreated(ItemDataAsset);// 告知资源浏览器
ItemDataAsset->GetOutermost()->MarkPackageDirty();// 标星号
}
- 在 UE4 中创建编辑器工具蓝图
父类选择 EditorUtilityObject
首先读取 DataTable
中的内容
再将数据表中的数据写入 DataAsset
中,并注意路径末尾 不能 以 / 结尾,否则创建的 DataAsset
无法保存。(忽略下面 Create New Data Asset
中的 ItemType
,如果不需要用 AssetManager
,就不需要在 C++ 中设置这个形参)
Package Path
可以进一步优化,否则只按上面的方式设置,在文件夹视图中,只会有一个 UAsset
。按下面的方式设置,UAsset
就正常了(推荐按下面的方式)
设置好之后,编译,保存。
- 运行编辑器工具控件
就会快速生成一堆 DataAsset
可以看到,DataTable
中的数据,已经完全导入到 DataAsset
中了,这样再也不必手动设置 DataAsset
中的数据了,也非常方便管理 DataAsset
中的数据。
具体效果可以看我这个视频
UE4 C++结合DataTable批量快速创建DataAsset
完