Write to file/save to log?


#1

Hey there! I want to evaluate SkookumScript for the Unreal Engine 4 as a means to conduct research. One of the most important functions I’ll need is to write data to file. I prefer CSV tables. SkookumScript is intriguing because I could run coroutines in parallel that collect data over the course of the experiment. Unfortunately, I haven’t found any Skookum Script class or method to write to files. What I’m currently looking for:

  • Write data to file that I’d retrieve from a slate interface (e.g. demographic data).
  • Save data that is collected during each trial.
  • Save data about events occurring during the experiment.
  • Save the location of an Actor 100 times a second.

Is this possible with SkookumScript? And if there’s no pure SkookumScript solution, how is it done using SkookumScript + Blueprints/C++?


#2

Hi and welcome Vaquero! :ue4: does not expose any raw file I/O features to blueprints, so this would be something that would need to be done in C++. If you’re just starting out, the important thing to remember is that :sk: can see and call any C++ class method that is marked with the UFUNCTION macro. So the general strategy is to make a new C++ class or C++ Blueprint Library that exposes helper functions to do file I/O and make sure they’re marked as UFUNCTION.

A very inflexible implementation could wrap the :ue4: provided method FFileHelper::SaveStringToFile, however this would mean doing your own CSV formatting. This is inflexible because there’s no way to append to the file other than re-writing it, so you would potentially have a very large string you’re concatenating to. That said, there’s a fairly famous example on the :ue4: wiki that illustrates saving strings to files.

If I were doing this myself, I would use Plog and write a simple C++ wrapper that would take a string and append it to an existing log file. Plog has built-in support for defining CSV fields and can handle appending to an open log as well as log roll-over at a specified size.


#3

There’s a way of appending a log to a file using FFileHelper::SaveStringToFile extra parameters.

This is a function i have that allows me to log a message into a file located in Project/Saved/Logs/MyFile.log

Header

/**
	* Append a string into a file. 
	* Uses default path "Project/Saved/Logs/"
	* Uses default extension ".log"
	* @param LogToAppend - Message to be appended into the .log file.
	* @param FileName - Name of the .log file.
	*/
	UFUNCTION(BlueprintCallable, Category = "Log")
		static void AppendLogToFile(const FString& LogToAppend, const FString& FileName);

Source

void UGenericFunctionLibrary::AppendLogToFile(const FString& LogToAppend, const FString& FileName)
{
	/// Validation
	if (LogToAppend.IsEmpty() || FileName.IsEmpty())
	{
		///#Warning
		UE_LOG(LogTemp, Warning, TEXT("CSWWarning - GenericFunctionLibrary.ApprendLogToFile() - LogToAppend or FileName is empty"));
		return;
	}
	/// Get "Project/Saved/Log/" path
	FString LogPath = FPaths::ProjectSavedDir() + TEXT("Logs/");
	FString FullPath = LogPath + FileName + TEXT(".log");
	/// Make "Project/Saved/Log/" in case it doesn't exists
	IFileManager::Get().MakeDirectory(*LogPath);
	/// AppendLog to FileName.log file
	FFileHelper::SaveStringToFile(LogToAppend + TEXT("\r\n"), *FullPath, FFileHelper::EEncodingOptions::AutoDetect, &IFileManager::Get(), EFileWrite::FILEWRITE_Append);
}

It could be improved by creating more functions for making backups of previous files or deleting previous files.

Hope it helps!