UE4 C++ 动态读写Datable

序言:

         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()
	
};

三、导入Datatable,选择自定义的数据结构

       选择刚刚创建的自定义结构体YourCppStruct 

​​​​​​​

 四、C++创建一个BlueprintLibrary类

   创建蓝图库,以便能够全局调用

#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<FString> 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<FString> 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<FProperty*> StructProps;
	for (TFieldIterator<FProperty> 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);
}

四、蓝图实现

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞起的猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值