Runtime DataTable - Import/Export text CSV or Google Sheet at runtime and auto-update structs and UObjects!

Hey ArchGodGiven, I updated the plugin last night and sent it to Epic, so now we wait for them to approve the update.

For the “CSV info invalid” issue, I haven’t seen this myself but I did make some changes in the last version that could be breaking. I took every measure to make sure it wouldn’t be, but testing can only catch so much. Can you explain this issue more, add some pictures? I can help you debug.

Hey, Jared
Great work there, I tried it and loved it as it’s easy to integrate!
While, for some reason when I open my previously working file today, there’s a message telling me the plugin is not installed but clearly I’ve installed it under the engine plugins > marketplace folder before.
Could you help me with that?
Screenshot 2022-04-18 172220

Thanks yan_kun!

This issue is from the last major update which was a complete rewrite of the plugin.

This fortunately can be easily solved, please follow the guide here: Runtime DataTable Documentation 4.27.4+ - Google Docs

A question : what’s the proper file path that i should enter into backup save path to point to the proper file in folder structure in packaged game?

I tried /Game/ and /Content/ but it doesn’t seem to work…

Hello czlowiek_kon!

The best way to accomplish this for saving would be to use the FPaths lib. You can get project and engine-defined paths this way. Personally, I like using Project save path. See this attachment which would save to “{Game Install directory}\Saved\MyStructSaved.csv”:

If you already have a csv you’d like to include with your packaged game, you can either include it unpacked with your game’s installation and use FPaths to find it, or you can pack and cook it using the /Game/ style pathing. You just have to be sure to include the asset in your packaging settings with “Additional Non-Asset Directories to Package” under “Advanced”.

OK this sounds sensible. One more - we are working on the project in editor, how does the paths differ from packaged build and the editor? Should i differante them using some kind of bool determining if it should follow the packagd/editor path?

As far as I know, anything that refers to a project path (like project root or project saved) refers to the project folder working in editor and the game install directory when working with a packaged game. As long as you design with that in mind you shouldn’t have to worry too much. Personally, I just always use Project Saved Dir in editor and packaged games.

I’m looking into that, thanks :slight_smile:

Another one though! I don’t remember finding that in the docu, bot is there a way that the RDT actually CREATES a google sheet? Or another sheet inside one google document.

What I’m trying to achieve is that our game generates data that we are interested in - interactions, number of shoots, hits, what happens with every enemy and so on - and this data is valuable for us :slight_smile:

Writing each battle to a single spreadsheet would be gold. I found a function that generates a csv file from an array. But it still needs an url, right?

But maybe this way - I generate a csv and then email it to a designated @ and then some poor soul converts the string into csv?

So basically - how would ypou approach that?

In my biased opinion, the best way would be to use GSheets Operator: GSheets Operator in Code Plugins - UE Marketplace

It’s a Swiss Army Knife of all things Google Sheets related in Unreal Engine. You can create sheets with this, get their IDs and pass them to RDT programmatically. You’d only need to set up a single blueprint to handle sheet creation and specify an ID for each function loop.

If you’re looking for a more economical solution, I’d recommend setting up a manual pooling system. Basically, you set up like 100 blank sheets beforehand and get their IDs then make a map in UE that tracks whether that ID was recently written to and if it was not, use that ID to write. Then in Google Sheets, use the scripting function to copy all sheets with data to another archive spreadsheet (where you can keep a record of the data) and clear each of the sheets in the pool. Then set up a time-based trigger to do this at a regular interval (like once an hour maybe? Depends on your game). Set up a similar trigger in blueprints to set all the booleans in the map to false, like saying to UE, “Ok, now all of the sheets are good to be written to.” Something like that.

Hi, I’m pretty new into blueprints so I would need some help with the Runtime Datatable plugin. Basically what I want is to read the last integer of my local csv column which is updated every second dy a device, then the integer should be displayed on the screen. How I can achieve this?

This is what I have so far.

Thanks in advance

Hello deedox, without seeing your CSV or struct it’s hard to say for sure, but it looks like you’ve almost got it. If the print after “Update Array from Csv Info” is ‘true’ then you should be able to just get the integer value straight from the Test Struct Array variable.

How many rows are in your CSV, not counting the header (column names)? You should end up with one array member in Test Struct Array per row in your CSV. You can either use a “Get” node to get all the data in a single row at a given row index or use a foreach loop, like you did with a string array, but instead use Test Struct Array. Then you can simply get the integer variable you want from the struct. Does that make sense?

Hi Jared, thank you.
This is how the csv looks like. The rows are autogenerated by a heartbeat measuring device and saved every second. Ijust want to display the last BPM value(second column) which is written by the device.

Ok, so yes that should be fine, with one caveat. The plugin expects a unique key identifier in the first column. In your sheet, ‘Date’ is the first column. This isn’t an issue on its own, just be aware that your struct should be a reflection of your sheet’s columns not counting the first ID column. Can you show me what your struct looks like? The type definition for Test Struct Array, I mean. The variables inside the struct.

Ok, so this should work just fine given you don’t need any other data in the CSV.

Pull out of the Test Struct Array variable pin and call “Get.” Pull out of the same pin again and call “Last Index” and plug it into the Index pin on the Get node. This will always get the final row of the struct.

Finally, pull out of the struct output pin on the “Get” node and choose “Break {Struct Name}.” Here you should be able to access “value” and do what you need to do.

Okay that works well, thanks. This is how it looks now.

The only problem I have is that this only works when I close my csv recording app and not on runtime. The print string stays empty… How I can fix that? Like I said the csv is saved every second.

This part is an OS limitation - if your program locks the file whilst writing to its IO stream then Unreal Engine can’t open it to read it.

If you can, edit the recording application to not lock the file, open the IO stream only when a write is needed and close it when it’s not, or write to something like Google Sheets.

If you can’t edit the recording application or stream/write the data in some other way, you may need to write a secondary application with elevated permissions that makes a copy of the file each second then use that copy instead.

It works now. I changed some parts inside the blueprint but I’m getting this error for some reason…

Another question I have is how I can make Unreal choose the csv file automatically? The recording app saves the files in order per session…

  1. Accessed None means there is no last index (I.E. the array is empty). Before you set LastBPMValue, throw a branch node in that checks if TestStructArray has a Length > 0.

  2. It looks like it saves the CSV files odinally (1, 2, 3… 12). You can either keep track of the last number CSV you referenced with an integer variable and increase it by one each time you are ready to pull the data then convert the integer variable to string. Just pull out of the pin and type “to string”. If that doesn’t work for you, you could try out Rama’s BP plugin which has a “Get Files” function. Get all the files in the folder and figure out which one you want to read. If you only have the latest CSV files in that folder you could get the length of the Files array from that node, convert it to string and use that to get the file you need.

Rama’s Plugin is found here: (39) Rama's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Refercing the CSV to an integer works nice! Thank you

I added also the Branch node but still getting an error.