虚幻4C++小轮子

论坛 期权论坛 脚本     
匿名技术用户   2021-1-11 21:17   229   0

一些常用的虚幻c++轮子的用法和总结,方便以后查找使用。这篇文章将是一个小例子集合。以供未来翻阅免得又搜索半天或者是自己造,为以后省一些功夫吧。

  1. 文件读写

  2. FString拓展

  3. TArray Sort排序

【1】文件读写

头文件:

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyFileHelper.generated.h"

/**
 * 
 */
UCLASS()
class NEWVERSION_API UMyFileHelper : public UBlueprintFunctionLibrary
{
 GENERATED_BODY()
 
public:
 
 UFUNCTION(BlueprintCallable)
 static void ReadTexFile(const FString& relativePath, FString& outString);

 UFUNCTION(BlueprintCallable)
 static void SaveTexFile(const FString& relativePath, const FString& inString);

};

源文件:

#include "MyFileHelper.h"
#include "Runtime/Core/Public/Misc/FileHelper.h"
#include "Runtime/Core/Public/Misc/Paths.h"

void UMyFileHelper::ReadTexFile(const FString& relativePath, FString& outString)
{
 if (relativePath.IsEmpty() == false)
 {
  FString absolutePath = FPaths::ProjectContentDir() + relativePath;
  //absolutePath = absolutePath.Replace(TEXT("/"), TEXT("\\"));
  FFileHelper::LoadFileToString(outString, absolutePath.GetCharArray().GetData());
 }
}

void UMyFileHelper::SaveTexFile(const FString& relativePath, const FString& inString)
{
 if (relativePath.IsEmpty() == false)
 {
  FString absolutePath = FPaths::ProjectContentDir() + relativePath;
  //absolutePath = absolutePath.Replace(TEXT("/"), TEXT("\\"));
  FFileHelper::SaveStringToFile(inString, absolutePath.GetCharArray().GetData());
 }
}

最后的结果:

这里用到了UE的两个轮子,一个是FileHelper,一个是FPaths。FileHelper封装了基本的IO功能,能方便读取,写入文本文件和二进制文件。FPaths内包含了大量和工程引擎路径相关的数据可以给我们提供路径信息。到FileHelper内部其实也可以很清楚理解其原理,只不过UE在这里帮我们做了很多封装。

【2】FString拓展

FString作为UE内部的字符串容器,其功能还是不够完善,所以我在这里给它写了些功能

(1)SplitAll

4.26版本的引擎默认有一个Split功能但是用起来还是不舒服

这个内置版本的split只能把字符串分割为左右两部分,比如AAA+BBB+CCC,以+号来分割字符串则会分割为AAA和BBB+CCC,这里我们需要把数据全部分开,所以我如下拓展,做了一个回调。

void SplitDeep(TArray<FString*>& splitSubString, FString& inString, const FString& signalString)
{
 if (inString.Contains(signalString))
 {
  FString* SL = new FString();
  FString* SR = new FString();
  inString.Split(signalString, SL, SR);
  splitSubString.Add(SL);
  if (SR->Len() > 0)
   SplitDeep(splitSubString, *SR, signalString);
 }
}

void UMyFileHelper::ReadTexFile(const FString& relativePath, FString& outString)
{
 if (relativePath.IsEmpty() == false)
 {
  FString absolutePath = FPaths::ProjectDir() + "Content/" + relativePath;
  FFileHelper::LoadFileToString(outString, absolutePath.GetCharArray().GetData());
  
  TArray<FString*>splitSubString;
  outString = outString.Replace(TEXT("\r\n"), TEXT("@"));
  
  SplitDeep(splitSubString, outString, "@");
 }
}

效果如下,这样就把它们分割到数组里了。

(2)RemoveAll

正常用户在调用remove的时候往往想要移除字符串的所有特定字符,然而UE的内置函数缺不是这样。我的修改如下

void RemoveDeep(FString& inString, const FString& subStringToMove)
{
 if (inString.Contains(subStringToMove))
 {
  int index = inString.Find(subStringToMove);
  inString.RemoveAt(index, subStringToMove.Len());
  RemoveDeep(inString, subStringToMove);
 }
}

void UMyFileHelper::ReadTexFile(const FString& relativePath, FString& outString)
{
 if (relativePath.IsEmpty() == false)
 {
  FString absolutePath = FPaths::ProjectDir() + "Content/" + relativePath;
  FFileHelper::LoadFileToString(outString, absolutePath.GetCharArray().GetData());
  
  TArray<FString*>splitSubString;
  outString = outString.Replace(TEXT("\r\n"), TEXT("@"));
  
  
  RemoveDeep(outString, "@");
  //SplitDeep(splitSubString, outString);
 }
}

效果如下:

(3)FindAll

同样UE缺乏寻找一个字符串里所有同类字符串的轮子,所以下面我撸了一个

void FindAll(TArray<int>& outPositionIndex, const FString& inString, const FString& signalString, int startPos = -1)
{
 if (inString.Contains(signalString) && startPos < inString.Len())
 {
  startPos = inString.Find(signalString, ESearchCase::IgnoreCase, ESearchDir::FromStart, startPos);
  outPositionIndex.Add(startPos);
  startPos+= signalString.Len();
  FindAll(outPositionIndex, inString, signalString, startPos);
 }
}

void UMyFileHelper::ReadTexFile(const FString& relativePath, FString& outString)
{
 TArray<int>FindPos;
 TArray<FString*>splitSubString;
 if (relativePath.IsEmpty() == false)
 {
  FString absolutePath = FPaths::ProjectDir() + "Content/" + relativePath;
  FFileHelper::LoadFileToString(outString, absolutePath.GetCharArray().GetData());
  outString = outString.Replace(TEXT("\r\n"), TEXT("@"));
  
  FindAll(FindPos, outString, "@");
  //RemoveDeep(outString, "@");
  //SplitDeep(splitSubString, outString, "@");
 }
}

效果如下

【3】TArray Sort排序

如果是我们自定义的类型,一个自定义类型的TArray对元素进行快排

struct MyStruct
{
 MyStruct(){}
 MyStruct(const float& indata){data = indata;}
 float data;
};

void UMyFileHelper::Test()
{
 TArray<MyStruct>arrayTest;
 arrayTest.Add(MyStruct(0));
 arrayTest.Add(MyStruct(2));
 arrayTest.Add(MyStruct(5));
 arrayTest.Add(MyStruct(7));
 arrayTest.Add(MyStruct(1));
 arrayTest.Add(MyStruct(3));

 arrayTest.Sort([](const MyStruct& A, const MyStruct& B){return A.data < B.data;});

}

效果如下:

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP