DataTable数据表在UE4中是一类重要的资产(Asset),引擎内置的函数并不支持运行时(Runtime)修改DataTable表,所以仿照源码取了相同的函数名称,但以下蓝图节点在打包之后仍然可以调用。
从ue4 源码DataTable.h和DataTableFunctionLibrary.h二个类中不难发现,DataTable支持动态读写操作的,其中UDataTable::CreateTableFromCSVString()和UDataTable :: CreateTableFromJSONString()二个函数尤其值得注意,这二个函数并未被WITH_EDITOR宏包裹,也就是在非编辑器模式下,仍可被调用。而二种函数中的输入参数CSVSting和JSONString既可以通过本地磁盘文件获得,也可以使用HTTP网络传输的数据来获得。所以在获得CSVString/JSONString之后,调用这二个函数,即可实现向DataTable中写入数据。
顾名思义,数据表就是以有意义且有用的方式将各种相关的数据归类的表格, 其中,数据字段可以是任何有效的 UObject 属性,包括资产引用。在设计师将 CSV 文件导入数据表前,程序员必须创建行容器以指示引擎如何解释数据。 这些数据表包含了列名,这些列名和基于代码的UStruct结构以及它的(子)变量一一对应, 这个UStruct的结构必须继承自FTableRowBase才可以被导入器辨识。
一般我们在设计游戏的时候都会用到大量的数据,如果在UE4里面直接修改会比较麻烦,这个时候就出现了数据表格,能够通过导入数据表格的形式来修改参数。
创建数据表格,放入到Content目录下面命名为DataTableFile(后面会用到),根据你们自己来就行,,Datable格式为CSV(不懂可以查看百度)
数据类型与下面自定义的数据类型相同
C++创建一个UObject的类,命名一个结构体,参数类型和名称可自己根据数据表格来命名。我们定义的结构体需要继承自FTableRowBase,因为只有这样虚幻才能识别数据表格。
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include"Engine/Classes/Engine/DataTable.h"
#include "MyObject.generated.h"
/**
*
*/
USTRUCT(BlueprintType)
struct FYourCppStruct : public FTableRowBase
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "YourCppStruct")
int32 IntegerValue;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "YourCppStruct")
float FloatValue;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "YourCppStruct")
FString StingValue;
};
UCLASS()
class DASD_API UMyObject : public UObject
{
GENERATED_BODY()
};
选择刚刚创建的自定义结构体YourCppStruct
创建蓝图库,以便能够全局调用
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Engine/DataTable.h"
#include "HAL/PlatformFilemanager.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Engine/DataTable.h"
#include "GenericArrayLibrary.generated.h"
//动态读取DataTable数据表格......
UFUNCTION(BlueprintCallable, DisplayName = "Fill Data Table from CSV String", Category = "DataTable")
static bool FillDataTableFromCSVString(UDataTable* DataTable, const FString& CSVString);
UFUNCTION(BlueprintCallable, DisplayName = "Fill Data Table from CSV File", Category = "DataTable")
static bool FillDataTableFromCSVFile(UDataTable* DataTable, const FString& CSVFilePath);
UFUNCTION(BlueprintCallable, DisplayName = "Fill Data Table from JSON String", Category = "DataTable")
static bool FillDataTableFromJSONString(UDataTable* DataTable, const FString& JSONString);
UFUNCTION(BlueprintCallable, DisplayName = "Fill Data Table from JSON File", Category = "DataTable")
static bool FillDataTableFromJSONFile(UDataTable* DataTable, const FString& JSONFilePath);
UFUNCTION(BlueprintCallable, DisplayName = "Get Table As CSV String", Category = "DataTable")
static void GetDataTableAsCSVString(UDataTable* DataTable, FString& CSVString);
UFUNCTION(BlueprintCallable, DisplayName = "Get Table As CSV File", Category = "DataTable")
static void GetDataTableAsCSVFile(UDataTable* DataTable, const FString& CSVFilePath);
bool UGenericArrayLibrary::FillDataTableFromCSVString(UDataTable* DataTable, const FString& CSVString)
{
if (!DataTable || (CSVString.Len() == 0))
{
return false;
}
// Call bulit-in function
TArray Errors = DataTable->CreateTableFromCSVString(CSVString);
if (Errors.Num())
{
// It has some error message
for (const FString& Error : Errors)
{
UE_LOG(LogTemp, Warning, TEXT("error1"));
}
return false;
}
UE_LOG(LogTemp, Warning, TEXT("true"));
return true;
}
bool UGenericArrayLibrary::FillDataTableFromCSVFile(UDataTable* DataTable, const FString& CSVFilePath)
{
FString CSVString;
if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*CSVFilePath))
{
// Supports all combination of ANSI/Unicode files and platforms.
FFileHelper::LoadFileToString(CSVString, *CSVFilePath);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("error2"));
return false;
}
return UGenericArrayLibrary::FillDataTableFromCSVString(DataTable, CSVString);
UE_LOG(LogTemp, Warning, TEXT("success"));
}
bool UGenericArrayLibrary::FillDataTableFromJSONString(UDataTable* DataTable, const FString& JSONString)
{
if (!DataTable || (JSONString.Len() == 0))
{
return false;
}
// Call bulit-in function
TArray Errors = DataTable->CreateTableFromJSONString(JSONString);
if (Errors.Num())
{
// It has some error message
for (const FString& Error : Errors)
{
}
return false;
}
return true;
}
bool UGenericArrayLibrary::FillDataTableFromJSONFile(UDataTable* DataTable, const FString& JSONFilePath)
{
FString JSONString;
if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*JSONFilePath))
{
// Supports all combination of ANSI/Unicode files and platforms.
FFileHelper::LoadFileToString(JSONString, *JSONFilePath);
}
else
{
return false;
}
return UGenericArrayLibrary::FillDataTableFromJSONString(DataTable, JSONString);
}
void UGenericArrayLibrary::GetDataTableAsCSVString(UDataTable* DataTable, FString& CSVString)
{
CSVString = FString();
if (!DataTable || (DataTable->RowStruct == nullptr))
{
return;
}
// First build array of properties
TArray StructProps;
for (TFieldIterator It(DataTable->RowStruct); It; ++It)
{
FProperty* Prop = *It;
check(Prop != nullptr);
StructProps.Add(Prop);
}
// First row, column titles, taken from properties
CSVString += TEXT("---");
for (int32 PropIdx = 0; PropIdx < StructProps.Num(); PropIdx++)
{
CSVString += TEXT(",");
CSVString += StructProps[PropIdx]->GetName();
}
CSVString += TEXT("\n");
// Now iterate over rows
for (auto RowIt = DataTable->GetRowMap().CreateConstIterator(); RowIt; ++RowIt)
{
FName RowName = RowIt.Key();
CSVString += RowName.ToString();
uint8* RowData = RowIt.Value();
for (int32 PropIdx = 0; PropIdx < StructProps.Num(); PropIdx++)
{
CSVString += TEXT(",");
CSVString += DataTableUtils::GetPropertyValueAsString(StructProps[PropIdx], RowData, EDataTableExportFlags::None);
}
CSVString += TEXT("\n");
}
}
void UGenericArrayLibrary::GetDataTableAsCSVFile(UDataTable* DataTable, const FString& CSVFilePath)
{
FString CSVString;
UGenericArrayLibrary::GetDataTableAsCSVString(DataTable, CSVString);
if (CSVString.Len() == 0)
{
return;
}
FFileHelper::SaveStringToFile(CSVString, *CSVFilePath, FFileHelper::EEncodingOptions::ForceUTF8);
}