Driving Gameplay with Data from Excel

I was able to import enums just using integers, and FText using text. However, I’m not sure if this text will be localized or not yet, or if it is just a string conversion. One issue I had was the data file needed to be the same name as the Struct, then I was given the option to choose the Struct when importing the data table.

Hi,

I managed to code a blueprint callable function to run the DataTable.GetRow function by doing the following:

FTableRowBase


USTRUCT(BlueprintType)
struct FLookUpTableRow : public FTableRowBase
{
	GENERATED_USTRUCT_BODY()

	/** Description specified in the table */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = LookUp)
	FString Description;
};

.h


UFUNCTION(BlueprintCallable, Category = DataTable)
static FLookUpTableRow GetLookUpTableRow(FDataTableRowHandle TableRowHandle);

.cpp


FLookUpTableRow UFunctionLibrary::GetLookUpTableRow(FDataTableRowHandle TableRowHandle)
{
	const FLookUpTableRow* Row = TableRowHandle.GetRow<FLookUpTableRow>();
	FLookUpTableRow LookUp;
	if (Row != NULL)
	{
		LookUp.Description = Row->Description;
	}
	return LookUp;
}

However, I’m trying to make a generic version of the code so I either :

  1. Don’t have to specify all the attributes to convert from the pointer back to my return type - Due to my currently limited C++ skills I can’t figure out how to *Cast *the pointer to my return type. Or, using my previous VB.NET knowledge, overload the constructor for the Struct to accept the values as inputs.
  2. My previous attempt was to attempt to return the FTableRowBase, but this didn’t work, perhaps because of above?

Any thoughts on how I can do this?

[=;89341]


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Enum)
TEnumAsByte<EElementalEnum::Type> PrimaryElementalType;

[/]

Thanks for this info, I was trying to do the same thing… any ideas how you would refer to an ENUM created within the Editor? Is it possible to use the imported data as an ENUM?

Cheers

M

[=Morpheus;90919]
Hi,

Thanks for this info, I was trying to do the same thing… any ideas how you would refer to an ENUM created within the Editor? Is it possible to use the imported data as an ENUM?

Cheers

M
[/]

I’m not sure about referring to ENUMs created with in blueprints, if I had to guess its probably more trouble than just moving the enums into code, and referencing the ones in code in your blue prints.

And do you mean to create an ENUM from imported data?

[= Conley;87081]
I added support for at least querying the tables in blueprints, that should release with 4.3:

[/]

So I specifically came into this thread to complain about the lack of BP support for at least querying DataTables :slight_smile: You totally destroyed my carefully prepared rant-asaurus :slight_smile: Very nice! Thank you .

[=Morpheus;90919]

  1. Don’t have to specify all the attributes to convert from the pointer back to my return type - Due to my currently limited C++ skills I can’t figure out how to *Cast *the pointer to my return type. Or, using my previous VB.NET knowledge, overload the constructor for the Struct to accept the values as inputs.
  2. My previous attempt was to attempt to return the FTableRowBase, but this didn’t work, perhaps because of above?

[/]

You can return *Row (in your case). This might be bad form for one reason or another though, I have to admit I really don’t know what I’m doing in C++ (this being the first thing I’ve ever done in it).

[=;90978]
I’m not sure about referring to ENUMs created with in blueprints, if I had to guess its probably more trouble than just moving the enums into code, and referencing the ones in code in your blue prints.
[/]

Yes, that’s what I meant, using ENUMS created in the editor… my thought was trying some kind of variation from the TAssetPtr but it didn’t work. I was trying my best not to hardcode the values in the C++ as I may want to add to the lists later.

[=;90978]
And do you mean to create an ENUM from imported data?
[/]

This is also what I meant, for example I have a list of say 20+ items, which is easier to manage in .CSV which I would then like to be able to use as an ENUM within Blueprints. Not sure if this is easy to do?

[=Leighroy;91045]
You can return *Row (in your case). This might be bad form for one reason or another though, I have to admit I really don’t know what I’m doing in C++ (this being the first thing I’ve ever done in it).
[/]

Thanks. Just discovered this myself after having a crash course in pointers :slight_smile:



FLookUpTableRow UFunctionLibrary::GetLookUpTableRow(FDataTableRowHandle TableRowHandle)
{
	const FLookUpTableRow* Row = TableRowHandle.GetRow<FLookUpTableRow>();
	return *Row;
}


Have somehow we set the value of a variable, using data from a data table?

https://docs.unrealengine.com/latest/images/Engine/Blueprints/UserGuide/Variables/new_variable_details.jpg

Hi there - Newb - How do you even define the structure?

If I do an add code to project there doesnt seem to be a class named FTableRowBase.

Can someone please give me a very quick run though of how to create the struct at the very top of this post - I should be able to wing it from there.

For example, click add code to project, select x as a class, copy the code into the .cpp file???, write this in the .h file, build.

Whenever I see any of these code bits I never know if it’s a .cpp file, and if it is, what goes in the .h file?

Thanks,

Dan

Hi ,

All the work is done in the header file. I’m not 100% sure if this is the best way to do it.

  1. Open up your project in Visual
  2. Navigate to your module folder in the Solution Explorer
  3. Right-click, Add->New Item…
  4. Select Header File(.h) and make sure the Location is changed to [Unreal Projects Path][ProjectName]\Source[ModuleName]
  5. Define your new struct using the example above, or copy and paste my code example below

is some sample code of the .h file I created for weapon data.


#pragma once

#include "Engine/DataTable.h"
#include "TableRows.generated.h"

/**
*
*/
USTRUCT(BlueprintType)
struct FWeaponTableRow : public FTableRowBase
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Enum)
	int32 WeaponType;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	float Caliber;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 Capacity;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 Length;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 BarrelLength;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	float Weight;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 MaximumRange;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 EffectiveRange;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 MuzzleVelocity;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	int32 RateOfFire;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Weapon)
	FString Country;
};

Make sure this line reflects the name of the header file.


#include "TableRows.generated.h"

Hope that helps?

Thank you for this article . CSV is a great format for storing table-oriented data locally and I use them everywhere possible. It would be cool if I could use SQL Queries, especially for enormous tables. My current plan is execute them via HTTP Request to a remote MySQL Database and serialize the response data in JSON format. I assume UE4 does not support JSON by default with a requirement for a JSON Plug-In. I’m still writing up the design doc for game, and will need to research this when the time comes.

Hi Morpheus,

Thanks so much for that - you’ve really got me off the blocks in tweaking UE4.

Dan

Hi All - error handling,

I’ve implemented a struct for storing some strings and some textures and it all worked fine last night (Thanks Morpheus). This morning though - after restarting the editor I suppose, I get a crash - ‘Cast of NULL to UScriptStruct failed’ when I open my level (not the project per se).

Any ideas about what might be causing this?

Thanks.

Does anyone know if it’s possible to use commas in a string stored in a data table in UE4. I’ve tried the usual method, double quotes around the string, but it seems that UE4 doesn’t recognize them and throws up a “has more cells than properties” error when you try to import. Am I missing something or is it a bug?

Trouble getting assets from DataTables

Help! I saw the note about “Get Data Table Row” in the 4.3 release notes and decided to try CSVs + blueprints for the first time, but I’m having a lot of problems. Retrieving simple types like int works fine, but all kinds of stuff goes wrong when I try to retrieve texture assets. It’s really unpredictable too. Even when I can retrieve them, I can’t find a way to get them as Texture2D either, but I’ll get to that.

First, I created a blank project in 4.3 with starter content. I added code for an Actor class and left it as the default code. Then I added the sample code from the article in the docs (“Data Driven Gameplay Elements”) that is basically the same as what’s in this thread. I made a CSV with just the following (modified to reference starter content textures):


Name,XPtoLvl,XP,Asset
1,0,0,"Texture2d'/Game/Textures/T_Brick_Clay_Beveled_D'"
2,1,2,"Texture2d'/Game/Textures/T_Concrete_Tiles_D'"
3,0,0,"Texture2d'/Game/Textures/T_Brick_Clay_Old_D'"
4,0,0,"Texture2d'/Game/Textures/T_Chair_M'"

I imported this CSV as a DataTable and selected the LevelUpData type. Worked fine. I then set up a level blueprint that, in response to the begin play event, tries to get the data from one of the rows in the DataTable, especially the Texture asset. In the process of trying to get this to work, I observed the following problems:

  1. Every time I open my project now, when I open my DataTable from the Content Browser, the DataTable Editor shows “None” for some of the assets:


In this state, if I attempt to retrieve one of those assets using the Get Data Table Row node and store it in a variable (of type “Texture”), I get nothing. The variable shows “Current value: none” when I inspect it while debugging the BP after execution of the variable set operation. To fix this, I have to right-click on my DataTable in the Content Browser and choose Reimport. Then when I open it I get this:


I don’t know why some of the assets have Texture2d’ at the beginning and others don’t, but only the ones without it can be successfully retrieved. Something causes assets to enter into this unusable state, which persists forever across editor sessions and I don’t know how to fix them.

  1. After going through this process of reimporting the DataTable, I then have to fix the level blueprint which has become damaged, looking like this:


I have to re-select the DataTable in the Get Data Table Row node, reconnect it to the Break node, and recompile the BP. Then it’s happy again.

  1. Even when I can successfully retrieve a texture asset and store it in a variable, I can never get it to be a Texture2D which is what I need. I want to apply it to a texture parameter of a dynamic material instance. In the BP debugger, it shows the contents of the variable as e.g. Package’/Game/Textures/T_Brick_Clay_Beveled_D. This is a different style than if I use a variable set node and hard-code the choice of texture by selecting it in that node - that shows as Texture2D’/Game/Textures/T_Brick_Clay_Beveled_D.T_Brick_Clay_Beveled_D’. (I don’t know what’s up with the repetition but it works.) Only that latter style can be successfully cast to Texture2D or fed to Set Texture Parameter Value. Assets coming from the Get Data Table Row node just don’t seem to be usable for some reason!

I tried changing the FTableRowBase-derived code to use TAssetPtr<UTexture2D> instead of TAssetPtr<UTexture>, recompiling it and restarting the editor as needed, but that resulted in failure as well. I could assign it to a Texture2D variable from the Get Data Table Row node, but inspecting the value of that variable in the BP editor still showed the sketchy Package’/Game/Textures/T_Brick_Clay_Beveled_D style. Attempting to feed this to Set Texture Parameter Value just crashes the engine. (I did submit a crash log.) 's what that graph looks like:


I’m kind of at the end of my rope . Any help would be greatly appreciated! Just knowing whether or not anyone has successfully used Texture2D assets from a DataTable would be really nice. I hope it’s just something I’m doing wrong, but it seems really really broken right now.

I’ve followed all the instructions for adding the stuct in c++ but I cannot get it to populate the combo box on import. The project compiles without any errors, but my new Row Type to show up when I import. The only one that shows up is “GameplayTagTable”

I’m using the example code verbatim (With the proper header stuff of course). What am I missing ??

I suggest you go through the programming quick start guide :

And then add your struct definition to the header file for that. Those are the steps I followed and it worked. There was also a report that you need a dummy Actor or something in your code in order for this to work:

By the way, I tried to use DataTables without any assets (just floats) and I still can’t get the Break node to stop getting disconnected from the Get Data Table Row node every time I open my project. I don’t need to reimport the DataTable, but I do need to re-select it in the Get Data Table Row node before that node can be reconnected to the Break node. What could be going wrong ? Is anyone able to re-open a project and have these two nodes keep the connection they had from last time?

I’m having the same problem. I think it might be because the assets haven’t been registered at the time the blueprint is checked. There’s some kind of function that makes the assets load dynamically which might fix this.

I think this happens.

1 project loads check the blueprints… What’s this data table? I can’t find it so break the node.

2 found the data table but the nodes in the blueprint are broken so it won’t compile.

3 them I’ve found that particularly with non-variable assets like textures - it won’t even populate the data table properly unless I re-save all of the missing assets.

I’d love a fix for this. I’ve made a 3d text generator but all of the meshes paths are stored in a csv which I have to remake each time.

Dan

Is it possible to localize the FText’s created from Data Spreed sheets?

I don’t know if this is a bug or if it’s not intended, but I’d like to be able to dynamically change the Data Table that is used in a blueprint during gameplay.

I’ve been working on a dialogue system that treats each Data Table as a script for a specific conversation. I’d like to be able to change the Data Table that is assigned to the character depending on cues in the gameplay. For example if the initial script asks the player if they want to start a quest and the player accepts the quest, I would like to change the script to one for the quest that is in progress(ie. Hey have you gone to the mage college yet? Oh okay, well come back to me when you have.) and then I’d like to change it again when the quest is completed.

Unfortunately there seems to be no way to create or promote a variable of type Data Table in Blueprint. Is this a bug or intended functionality? Will this be changed in the future?

No promote to Variable option. Also can’t create one manually by creating a new variable. It seems inconsistent to have a data type that you cannot GET/SET.

It appears Row Names can only be numerical at this time…is it possible to allow any name in the future? It would seem that it would make sense since the type is ‘FName’ but if I put anything put numbers in that column the whole thing completely breaks.