Questions regarding reading data from files.

Hey! I’m pretty new to C++ and UE4, and I’m currently working on a small project (a flight game).

My main problem is writing code which will let me load files and data into the engine via text files (for mod support). By following a simple tutorial, I managed to get a cool node which lets me load a txt file into a string, which I can then parse into an array and so on. I have no idea how to take it from there, though.

Here’s how I decided to manage all this:
-A folder with txt files; these files specify where data for these aircraft can be found (filepaths). For example, such a file may contain:
VIPER, user/data/viper.txt, user/models/viper.fbx, user/coll/vipercoll.fbx
HORNET, user/data/hornet.txt, user/models/hornet.fbx, user/coll/hornetcoll.fbx
etc
-These files are then read with the data split into arrays, each one with 4 values which contain their filepaths (aircraft name, aircraft data file, aircraft static model and aircraft collision model).

I have the following questions:

  1. How can I read these files and split the data into arrays? I have a vague idea on how to return a list of all files from a folder, and that’s about it:


#include <filesystem>
namespace fs = std::filesystem;
int main() {
std::string path = "/aircraft"; for (const auto & entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
}


I’ve also thought about following the tutorial I watched (read the file into a string, parse it into an array and store them as variables) but the problem is that I have multiple, differently named text files instead of one defined by this code:



#include "lstloader.h"
#include <Runtime/Core/Public/Misc/Paths.h>
#include <Runtime/Core/Public/HAL/PlatformFilemanager.h>

FString UDATALOADER::LoadFileToString(FString Filename)
{

FString directory = FPaths::GameDevelopersDir();
FString result;
IPlatformFile& file = FPlatformFileManager::Get().GetPlatformFile();

if (file.CreateDirectory(*directory)) {
FString myFile = directory + "/" + Filename;
FFileHelper::LoadFileToString(result, *myFile);

}
return result;
}


Should I pursue the idea further, or is it simply too stupid to work? I have a vague idea on how I can modify it to suit my needs, but I’m honestly too inexperienced to know how I should do it.

  1. How do I access these arrays later on, inside the engine? For selecting aircraft and loading them in-game, that is.

  2. Would these arrays be global, or only available inside the blueprint which uses them?

  3. What’s the default directory for the code/engine to look in for finding files? Sorry if it’s a dumb question, but I’d like to start figuring out how the filepath lists and so on.

Thanks in advance.

Let’s say you have a (BlueprintType) struct:



USTRUCT(BlueprintType)
struct FMyStructType
{

GENERATED_BODY()

UPROPERTY()   bool _Bool;
UPROPERTY()   uint8 _Byte;
UPROPERTY()   int32 _Int;
UPROPERTY()   int64 _Int64;
UPROPERTY()   float _Float;
UPROPERTY()   TArray<FString>_Strings;
UPROPERTY()   TArray<FName> _Names;

}


If you add to your Build.cs, the module “JSonUtilities”, the engine simplifies to problem for you:



PublicDependencyModuleNames.AddRange
(
   new string] {
      "Core",
      "Engine",
      "CoreUObject",
      "**Json**",
      "**JsonUtilities**"
   }
);


You can use your struct as usual, add/remove values to the arrays within that struct…
When you want to record the data, you can convert your struct to Json, using utilities API. Very simple:
FJsonObjectConverter::UStructToJsonObjectString | Unreal Engine Documentation



FString NewData;
FJsonObjectConverter::UStructToJsonObjectString<**FMyStructType**>( myStruct, NewData, 0, 0 );


And write it down to a file:



FString myFilePath = FPaths::Combine(FPaths::ProjectUserDir(), TEXT("myData.txt"));
FFileHelper::SaveStringToFile(Data, *myFilePath, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM);


When you need to load it back, open the file and convert it back from Json text to struct:



FString LoadData;
FFileHelper::LoadFileToString(LoadData, *myFilePath);

FJsonObjectConverter::JsonObjectStringToUStruct<**FMyStructType**>(LoadData, &myStruct, 0, 0);


You then can use myStruct as usual, all its data, including arrays, were loaded from disk for you.
This doesn’t work with complex data types (such as object pointers), but for blueprint structs it’s a Json engine that you can abuse and works just fine.

Huge thanks, lots of great stuff in there.

Now just gotta figure out how to get and group my data, looks like fun :stuck_out_tongue: