Thursday, 15 October 2015

String to Object Dilemma In Unreal Engine 4

A subject that often pops up on Epic's UE4 Answer Hub is the question of whether to reference assets in Blueprints via their name or a string. This is obviously not a good approach but why not and how do you get around it? I hope to answer both these questions for you.

Why Not Reference Asset by String?

When you make a variable in Blueprint or select a specific asset in a node you see its name. Although it looks to all intents and purposes the same as a string, its actually a pointer which can directly pinpoint the asset, component or variable in memory. A string is just a collection of characters which can represent the name, so Unreal has to read the string, convert it to a name and then go and find the reference.

So why is this an issue? Well let's picture the data of an Unreal project like a long street. You want to visit Mr MaterialAssetNamedMyMaterial, but all the houses look the same and there are thousands of them. An asset's name acting as a pointer is like having Mr MaterialAssetNamedMyMaterial's address in front of you, but if you just have a string containing his name you've got no option other than knocking on doors to try and find him. By the time you reach his house at number 5,654 time has ticked on quite substantially.

That sounds very much like a database search, and that's pretty much what it is. Game engine coders know that database searches are too slow to be effective for real-time, but this concept isn't quite so obvious to people like us - designers and artists - who use Blueprints rather than direct code, while those coming from the fields of web or app development will be used to database searching as part of how they work. In fact I ended up having to ask an experienced game coder.

So this is why Blueprints do not support references by name; otherwise the system would just crawl under the weight of data searches. However, the real problem in practice is when assets need to be referenced in Blueprints at scale. It's tedious enough manually adding a dozen objects but what about when adding hundreds? If referencing them by string is not an option, then there must be a another way to deal with large-scale data sets in Blueprint. Well, yes there is and Epic have given it to you.

Data Driven Elements

During development, game designers have to juggle a lot of variables, often make sweeping changes to test gameplay many times to get the elusive fun factor spot on. To save designers getting repetitive strain from having to modify large numbers of assets, there needs to be a way to enter, edit and manage sets of data easily and centrally. To facilitate this, UE4 gives you the ability to import CSV files, which can be created and edited in your favourite spreadsheet software then loaded into Unreal.

The data in these CSV files can be used to reference assets, variables and objects by name and handle their associated data; UE4 will automatically make a pointer for each asset for you when you import the CSV file.

Looking at the documentation seems to suggest you need some C++ experience to achieve this, but you can do this with just Blueprints.

How to Import a CSV File

First you need to tell UE4 what data to expect from the CSV file, so you need to make a Structure. Right click in the asset browser pane and select Blueprints > Structure.

Open the structure and you'll see that you can add variables in much the same way as you do in other Blueprints. Add a variable for each column of your spreadsheet data apart from the first column.

Take a look at the screenshots below. The first is the CSV file when loaded into UE4 and the second is the Structure derived from it. You can see that the first column in the CSV file isn't replicated in a Structure. Instead, it as a key to the data in the other columns. UE4 refers to these as the 'row names' and uses them as pointers to the specific rows in the CSV.

Some of the data types UE4 expects can be quite verbose so you may want to split the data down into simpler items then recombine them later in the Blueprint. Colors are a usual candidate for this, splitting them into Floats to represent the component red, green and blue values (plus alpha if required).

On the right hand side of the Structure you will see the default values for each variable appear, You can leave these empty.

When you import your CSV file (which we'll do in a minute) it will be turned into a DataTable. When the DataTable is created you'll want UE4 to make a pointer to your assets. If UE4 fails to make a pointer. what you see when you open the DataTable is "none" where the asset name should be.

UE4 seems to be good at finding some asset types itself but for others it needs help. If after importing your CSV file you have "none" where you should have an asset name, drag instances of the problem assets into the current map so they are present in the world, then reimport the CSV data, This helps UE4 locate the asset.

Next, import your CSV data in the same way you'd import a new mesh or texture.

You'll then be presented with the DataTable Options dialog. Select to Import as: DataTable then choose your Structure you made previously as the Table Row Type.

You will now see DataTable assets along with your Structure assets.

Working With CSV Data

Once you have some CSV data with asset pointers in place you can use Blueprints to implement the data in any way you like. Here are the Blueprint nodes that you'll need to use.

In your Blueprint, right click to bring up the nodes menu and type "data table" to see the DataTable nodes available.

A simple way to use a DataTable is to use the Get DataTable Row node to select a data table by name. This name is what's held in the first column of your CSV file (as mentioned above), the one that you didn't reference when you made the Structure Asset.

From the node output, you can then drag off a connection to Break <datatable name> which will give you access to all the juicy data in your CSV file without having to manually create lots of individual variables.

Shown below is a node which features data from part of our UK Sign asset set.

Last Word...

Before finishing this post, there's one point to note:

If you notice that reimporting a CSV file into UE4 isn't behaving like you'd expect, it could be because it will fail to reimport if Excel still has the file open. Epic are working on a fix for this but there is a sort of workaround.

If you work on a file saved in .xlsx format (which also allows you to colour code rows and the like), you can save it in CSV format and then save again as an .xlsx. This will disassociate the file that's open in Excel from the version in UE4, allowing you to freely import the CSV file into UE4.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.