// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataTable.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "LoadCsvFile.generated.h"
USTRUCT(BlueprintType)
struct FMyStruct
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FString> test;
};
USTRUCT(BlueprintType)
struct FMyStructs
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FMyStruct> test;
};
//形态键名字组成的结构体
USTRUCT(BlueprintType)
struct FMyDeformerNameStructs
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FName> name;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<int> data_num;//形态键对应这边动捕数据数组的索引
};
/**
*
*/
UCLASS()
class ANIMCSV_API ULoadCsvFile : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, meta = (DisplayName = "LoadExcel", Keywords = "LoadExcel"), Category = "Custom")
static TArray<FMyStruct> DataReadExcelFunction(FString name,FString csvdir);
UFUNCTION(BlueprintCallable, meta = (DisplayName = "GetFaceData", Keywords = "LoadExcel"), Category = "Custom")
static TArray<FMyStruct> GetFaceData(TArray<FMyStruct> data);
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "LoadCsvFile.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Serialization/Csv/CsvParser.h"
TArray<FMyStruct> ULoadCsvFile::DataReadExcelFunction(FString name, FString csvdir)
{
UE_LOG(LogTemp, Warning, TEXT("Excel Animation Dir:%s"), *FPaths::RootDir());
FString csvFile = csvdir + name + ".csv";
TArray<TArray<const TCHAR*>> content;
TArray<FMyStruct> contents;
if (FPaths::FileExists(csvFile))
{
FString FileContent;
//Read the csv file
FFileHelper::LoadFileToString(FileContent, *csvFile);
FCsvParser* csvfiles = new FCsvParser(FileContent);
//csvfiles.
content = csvfiles->GetRows();
for (const TArray<const TCHAR*>& val : content){
FMyStruct contents_;
for (const TCHAR* a : val) {
contents_.test.Add(a);
}
contents.Add(contents_);
}
return contents;
}
else {
return contents;
}
}
// AU45_r双目眨眼16 Fcl_EYE_Close合上眼睡觉
// AU26_r双唇分开看见舌头15 Fcl_MTH_Surprised张大嘴
// AU25_r双唇分开露出牙齿14 Fcl_MTH_E 笑容露牙齿
// AU23_r收紧双唇成一字13 Fcl_MTH_Fun 抿嘴笑
// AU20_r嘴唇向后方拉扯12 Fcl_MTH_I 嘴唇向后牙咧嘴
// AU17_r挤动下唇向上顶11 Fcl_MTH_U 樱桃小口嘟嘟嘴
// AU15_r嘴唇垂直向下拉动10 Fcl_MTH_Sorrow 张小嘴
// AU14_r嘴唇向牙齿收缩9 Fcl_MTH_I 嘴唇向后牙咧嘴
// AU12_r上扬嘴角8 Fcl_MTH_A 张嘴
// AU10_r抬起上嘴唇7 Fcl_MTH_O 张嘴
// AU09_r收缩提起鼻子6 Fcl_MTH_U 樱桃小口嘟嘟嘴
// AU07_r眼镜收缩5 Fcl_EYE_Surprised瞳孔缩放
// AU06_r抬起脸颊4 Fcl_BRW_Surprised内眉毛上挑
// AU05_r抬起上眼皮3 Fcl_EYE_Spread抬起上眼皮
// AU04_r眉毛整体低垂2 Fcl_BRW_Angry内眉毛下降
// AU02_r外部眉毛抬起1 Fcl_BRW_Sorrow外眉毛下降
// AU01_r内部眉毛抬起0 Fcl_BRW_Surprised内眉毛上挑
TArray<FMyStruct> ULoadCsvFile::GetFaceData(TArray<FMyStruct> data)
{
TArray<FString> AUStrings={" AU01_r"," AU02_r"," AU04_r"," AU05_r"," AU06_r"," AU07_r"," AU09_r",
" AU10_r"," AU12_r"," AU14_r"," AU15_r"," AU17_r"," AU20_r"," AU23_r"," AU25_r"," AU26_r"," AU45_r"};
TArray<int> au_num;//记录每个au所处的数组位置编号
TArray<FMyStruct> return_data;
TArray<FString> data_strs = data[0].test;//第一行表头
for(int i=0; i<data_strs.Num(); i++)//有多少列
{
for(FString au : AUStrings)
{
if(data_strs[i] == au)//遍历查找所有au
{
au_num.Add(i);
}
}
}
for(FMyStruct hang : data)//每一行的这一项
{
FMyStruct hang_;//创建新的空行
for(int i : au_num)//au列
{
hang_.test.Add(hang.test[i]);//给空行添加所有au的值
}
return_data.Add(hang_);//把需要的数据保存起来
}
return return_data;
}
可以看到我把加载的CSV做成蓝图节点了,方便传入路径进行加载
网上别的方式是做成表,但是有些表有重复表头,所以会报错。
我这里就是直接取出来了,存在数组里
最后看看cs文件,不知道能不能用上