【转载】UE4 C++ 利用 DataTable 读取 CSV 文件

865 阅读2分钟

原文链接:UE4 C++ 利用 DataTable 读取 CSV 文件(无需在蓝图中创建 DataTable)

旧方法

网上有许多用 C++ 读取 CSV 文件的帖子,刚开始用了一个方法可以在打开 CSV 文件的同时,也可以读取到文件里面的内容,但是这个方法在 4.26 会打包报错。该方法的大概流程为:

  1. 在 C++ 里面写一个继承于 FTableRowBase 的结构体

  2. 用这个结构体在编辑器里面创建一个 DataTable

  3. 利用函数 UDataTableFunctionLibrary::FillDataTableFromCSVFile(DataTable, CSVPath); 将 CSV 表中的数据写入刚创建的表中(该函数在 4.26 打包中,会报错
    (7.12 补充, 查阅该函数的属性宏标识:
    UFUNCTION(BlueprintCallable, Category = "Editor Scripting | DataTable", DisplayName = "Fill Data Table from CSV File")编辑器脚本,所以不能打包)

  4. 得到表的每行的名字,根据名字在表中查找到这一行的数据,从而在 C++ 中得到 CSV 文件中的数据

新方法

下面提供一种可以打包的版本(但是该版本在 CSV 文件打开的时候,会出现访问冲突而读取不到 CSV 文件)

  1. 在 C++ 文件中添加头文件
#include "Engine/DataTable.h"
  1. 创建一个结构体来储存 CSV 文件中的信息,该结构体得继承于 FTableRowBase
USTRUCT(BlueprintType)
struct  FStructInfo : public  FTableRowBase
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString Name;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		float Speed = 1.0f;
};
  1. 创建函数读取 CSV 中的数据创建 DataTable
UDataTable* ACSVManager::ReadCSVFile(FString csvPath)
{

	FString Data;
	if (FFileHelper::LoadFileToString(Data, *csvPath))         // 读取 CSV 文件
	{
		UDataTable* Datatable = NewObject<UDataTable>();   // 定义 datatable
		Datatable->RowStruct = FStructInfo::StaticStruct();// 定义 datatable 的结构体
		Datatable->CreateTableFromCSVString(Data);         // 将 csv 中的数据写入 datatable
		return Datatable ? Datatable : NULL;
	}
	return NULL;
}
  1. 将数据提取出来到结构体数组,方便操作
FString contextString;
TArray<FStructInfo*> structInfos;
Datatable ->GetAllRows(contextString, structInfos);

好了,现在就大功完成啦,之前存在 CSV 文件里的数据一行、一行的,全部都复制到了 structInfos 这个结构体数组中啦,值得注意的是 structInfos 里面的每一条消息都是有用消息,我们知道一张表的第一行是标题,但在 structInfos 中的下标为 0 的数据并不是标题信息,而是(原表的)第二行信息,还是非常方便的。