x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

DataTableRowHandle to Get Data table row: Only literal data table is supported

Hi,

I'm trying to connect data table ref pin from DataTableRowHandle to Get Data Table Row, like the following picture shows.

But it says "Only literal data table is supported" and I can't connect the pin.

I tried both UE 4.6.1 and 4.7 preview 6 and the result is the same.

Is there something I did wrong or UE4 just doesn't support this?

Appreciate any help, thanks. :)

alt text

Product Version: Not Selected
Tags:
datatable.png (89.7 kB)
more ▼

asked Feb 12 '15 at 03:40 AM in Everything Else

avatar image

CrispyVitamin
76 4 8 14

avatar image Adam Davis STAFF Feb 12 '15 at 06:15 PM

Have you tried dragging off of the Break DataTableRowHandle "Data Table" pin and call the "Get Data Table Row" from there?

avatar image CrispyVitamin Feb 13 '15 at 01:52 AM

Yes I tried. Break DataTableRowHandle showed up but pins still not connected.

avatar image CrispyVitamin Feb 13 '15 at 02:53 AM

The result is like the following pictures

alt text

alt text

alt text

alt text

datatable1.png (34.6 kB)
datatable2.png (52.2 kB)
datatable3.png (40.7 kB)
datatable4.png (49.5 kB)
avatar image ScottSpadea Apr 25 '16 at 11:03 PM

GetDataTableRow outputs a specific type of struct, so changing the type of DataTable with a variable at runtime, would also change the type of struct it outputs, which would break its connection to the BreakStruct node.

it would be nice if GetDataTableRow just output a blob of Bytes in binary, and we could cast that blob to a specific struct, but structs don't allow casting or inheritance to make them as light weight as possible.

since UE4 doesn't have struct inheritance and struct casting, you should design data tables to hold data for categories of generic functionality, rather than specific objects. so you can have a weapons data table, but you shouldn't have a shotgun data table, shotgun should be just a row, not a table. each type of enemy should not have its own data table, they should each be a row in an Enemies data table.

avatar image Douglas Lassance Apr 26 '16 at 12:32 AM

I actually tried to fix that by branching the engine but the variable output pin was a problem. And like you said you cannot cast structs. Only solution I can see is some more advance logic when processing the input table. A new argument could be used to set the type of struct that that the node will support.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

3 answers: sort voted first

Hi,

I've found a workaround to this issue.

I found these codes from answer hub a while ago, I can't find original post though, so I just post it here.

And I've made some modifications to it to prevent some crash issue.

Create a C++ blueprint function library and add these codes:

.h

 UFUNCTION(BlueprintCallable, Category = "DataTable")
     static FEnemyFireStruct GetRowByName(UDataTable* dataTable, FName pName, bool& result); 

.cpp

 FEnemyFireStruct UUBPFuncLib::GetRowByName(UDataTable* dataTable, FName pName, bool& result)
 {
     result = true;
     FEnemyFireStruct* data = dataTable->FindRow<FEnemyFireStruct>(pName, "", false);
     if (data == NULL)
     {
         result = false;
         return FEnemyFireStruct();
     }
 
     return *data;
 }

FEnemyFireStruct is my custom struct, you can replace with your own struct.

Then you can create a data table handle in blueprint, assign data table to it.

By using this way you can have multiple child share one common parent with same code base and can still assign different data table value to different child.

This isn't entirely beautiful because you have to create a new function for each struct you want to use, but this is the only option I found workable currently.

alt text

alt text

dt1.png (14.8 kB)
dt2.png (81.9 kB)
more ▼

answered Jun 24 '15 at 06:22 AM

avatar image

CrispyVitamin
76 4 8 14

avatar image NiekPixelpool Jan 11 '17 at 11:21 AM

is it possible to make the struct for this variable? would be nice since i am trying to write a function for datatables that use different structs :)

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

"By design" seems like a poor decision on this one. I am using data tables to define dozens of settings for various weapons, and based on player purchase choices, I need to select the correct table. This info now needs to be replicated for every weapon because I can't promote the get data table input to a variable.

more ▼

answered Aug 15 '16 at 11:02 PM

avatar image

Alwaysusa
41 1 5 7

avatar image bricefr Aug 23 '16 at 04:33 AM

+1

Same thing for me: stuck "by design"! ;-) Have to found another way.

avatar image ScottSpadea Aug 23 '16 at 07:11 PM

why not put every weapon in your game in the same data table?

avatar image Alwaysusa Aug 23 '16 at 09:15 PM

Nothing is stopping me doing that - but that would mean a data table with well over 200 rows in my case. It's much easier to split into smaller data sets, not just in BP, but also for the designers working with the data tables.

Being able to specify the data table through through a variable rather than a static value would make the entire process easier for all departments.

avatar image Douglas Lassance Aug 24 '16 at 02:49 AM

I tried to change the source code to remove the literal only restriction. Sadly, I quickly realized why they took that route. Indeed, any other way results in unpredictable output types. Adding the fact that you cannot cast structs, it becomes apparent that they will not be able to address this concern easily.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Hi CrispyVitamin,

I did a bit more testing. the reason it is giving you this is because the input is looking for the full data table to call from, not just an individual component. The "Break DataTableRowHandle" takes specific data from within a data table and breaks it down into smaller components, instead of keeping the data table intact. If you click the dropdown menu under "Data Table" you should be able to get access to the full Data Tables you have available to you.

more ▼

answered Feb 13 '15 at 04:22 PM

avatar image CrispyVitamin Feb 13 '15 at 05:00 PM

Hi Adam,

Thanks for your detailed reply. I got a bit more little questions, hope you don't mind. :)

If I can't connect the pins, why does the action menu shows "Break DataTableRowHandle"? Since it can't be used here, it seems odd to have that option in the menu.

And the reason I want to connect the pins is because I want to store data table ref as an variable in DataTableRowHandles, and use them when needed.

Is there any chance you might add the feature or something similar so we can dynamically assign data table ref to "Get Data Table Row"?

It would make things much easier when using CSV data tables.

Thanks. :)

avatar image Douglas Lassance Mar 16 '15 at 10:28 AM

I am also interested in that answer. I have characters inheriting from each-other and therefore I would simply like to store a reference to their respective data table and do all the logic a single time in the character base class. Seems to me like a pretty common use for a data driven system.

avatar image Adam Davis STAFF Mar 16 '15 at 07:56 PM

I've entered a bug report, UE-11952, to be assessed by the development staff on as I've discovered that you cannot promote the data table input to a variable, which may mean that it is an error and not intended functionality.

avatar image Colbra Mar 19 '15 at 03:10 AM

yes I've encountered the same bug while working with it, is there any work around currently ?

avatar image Adam Davis STAFF Mar 19 '15 at 02:36 PM

Unfortunately at present no, the only solution is to add the data table as a hard value in the node.

avatar image Everynone Jun 13 '15 at 08:42 AM

Since both Data Tables and Structs are working neatly in 4.8, this feature could use some love. There are clumsy workarounds, of course, usually resulting in unnecessary spaghetti, though.

Any chances for UE-11952 to be reassessed?

avatar image Adam Davis STAFF Jun 15 '15 at 03:44 PM

Hi Everynone,

UE-11952 has been closed as by design. The reason this is required is that, when reading data table entries, a literal value is required to determine what rows are available to get. Without the literal, this information cannot be determined.

avatar image Douglas Lassance Jun 15 '15 at 03:51 PM

What is the workflow for having different character BP referencing their respective data table then? In other words how can I inherit from my base character class where all the logic to access the data in the table is implemented without having to override these methods for each child of that class?

avatar image Adam Davis STAFF Jun 16 '15 at 05:42 PM

Hi Douglas Lassance,

I just want to make sure I understand what you mean. Are you asking how would a child blueprint access a function that selects a specific datatable row from the parent blueprint without overriding the function in the child blueprint?

avatar image Douglas Lassance Jun 23 '15 at 12:59 PM

Yes. Let me just give you a very simple example to make sure we understand each-other. We have two children of a custom Magician class, Merlin and Gandalf. Magician implements a CastSpell method which will query the spell from a spell table. There is two spell tables, Merlin_Spells and Gandalf_Spells. I want to be able to edit a Spells variable on Merlin pointing the corresponding table the same way I would point to the corresponding skeletal mesh, which, obviously is not the same as Gandalf's. If the table remains a literal argument like it is now, the only way to have such a system working would be to re-implement CastSpell on each Magician which would suck.

avatar image Adam Davis STAFF Jun 23 '15 at 03:05 PM

What I would probably do at this point (I haven't tested this myself with data tables but the logic should work) is set up an enum. In this example, have an enum with one selection being Gandalf and one Merlin. When you spawn the character, depending on which you are set the enum accordingly. Place a switch on enum in front of the data table functionality, so that, when the enum is set in your player character, the data accesses only that information that the enum determines is relevant to that player. So Gandalf_Spells for Gandalf and Merlin_Spells for Merlin. This would halt any need to redo functionality and give you direct control over which values you are attempting to access.

avatar image Douglas Lassance Jun 23 '15 at 03:15 PM

It is not very elegant to have to set both the class and the enum in order to spawn Gandalf. It is also not ideal to have to add some logic in the base class each time there is a new magician. But I suppose that could be an acceptable workaround. I am honestly not sure why they made it impossible to make variables of type DataTable.

avatar image Adam Davis STAFF Jun 23 '15 at 04:02 PM

In this case you wouldn't require the enum to spawn per se, you'd use the enum to determine what dataset to access from the parent blueprint. This isn't a workaround so much as a feasible way to do the task you are looking for. Another would be to put the datatable information on a custom event and call the custom event for Gandalf when the actor==gandalf, or merlin for merlin etc. I figured the enum is significantly more performant and easier to set up than some other options that are available.

avatar image Douglas Lassance Jun 24 '15 at 10:27 AM

What I mean is that in an ideal world, spawning a Gandalf should be enough to have what you want. Spawning a Gandalf plus having to specify which table to use is redundant simply because it is something you will always have to do for Gandalf. I am saying your solution is a workaround because it is discouraging inheritance. Imagine for a second if you had to do the same for specifying the skeletal mesh or any other property of the magician class. Now there is really no reason to have a Gandalf and Merlin class anymore, a single Magician class with an MagicianType enumerator at spawn time is all you need. Sadly, I feel this is not how UE encourages you to work for anything else.

avatar image CrispyVitamin Jun 24 '15 at 01:58 PM

Hi Douglas, I've posted a workable solution(for my project) to this inheritance issue below. Have a look, it may helps you. :)

avatar image ScottSpadea Apr 25 '16 at 07:26 PM

i think in the Merlin/Gandalf example, you should probably combine your spells into a single data table that every character uses. accessing data tables is less high maintenance when data tables are used on categories of things, rather than instances. so its fine to have a datatable of character stats, but you shouldn't have a specific data table for each character.

so if you have more than one data table that use the same struct, they should probably be combined into the same data table. Merlin can be given an array of names that represents his spell collection, and his spell data can be looked up in the same spell table everyone uses for all spells.

data tables are data oriented, rather than object oriented, so you should not think of data belonging to a specific object, like Merlin, but instead, think of data as belonging to a general functionality, like spell casting.

using data tables this way, allows you to quickly create new characters that combine the spells of Merlin and Gandalf, so you can make a shape shifter like Shang Tsung from Mortal Kombat or Mokujin from Tekken, who can use any move in the game, and you can make custom character editors in your game, which allows you to choose moves from a global list, like the create a skater from tony hawk games.

when you separate data from specific class hierarchies, it gives you alot of freedom and modularity, where any character can perform any move, and any weapon can fire any projectile. if you take it a step further, and stick with data oriented design, Merlin and Gandalf should not even be specific actors or objects, they should just be rows in a character Data Table.

so instead of spawning a Merlin Actor that looks up Merlin_Spells, you should spawn a generic character, and pass it a character name, like Merlin, so on begin play, it can look up a list of available spell names from a CharacterSpells data table, then combine that list with collected spells, by loading a SaveGame.

avatar image Douglas Lassance Apr 25 '16 at 07:59 PM

I see what you mean. Use them more like you would with a real database. A table stores one type of entity and the "hierarchization" of this data comes from the API on top. Following your way, my Spell structure should probably have a Magician key that can be set to Gandalf or Merlin. That would work nicely.

avatar image ScottSpadea Apr 25 '16 at 08:50 PM

your spell structure should probably only contain data related to each spell, and not contain anything about whether a specific character is allowed to use the spell, because that would be high maintenance, and lower the potential for modularity. to control which spells a character can use, you should use an array of spell names in your base character, which can be loaded from a separate data table.

so a generic character is given the name Merlin. using that name, it looks up a data table called CharacterSpellsTable, where each row has an array of names, and it copies this array into the character's AvailableSpells. when you use a spell, you get a name from the AvailableSpells, and use it to look up spell data in a separate SpellsTable.

spell data only describes the statistics of a spell. "who owns which spells" is a separate concept, which is not part of spell data, but instead part of character data or inventory data.

ideally, ownership should be editable at runtime, so designers can add any spell to any character, in game.

if you want to create a new character, which uses only existing spells, it should not require editing the spells data table. if you want to create a new spell, it should not require knowing which characters can exist.

the idea is, that programmers should give designers as much freedom as possible for mixing and matching any character with any spell, and the designers should be the ones who limit the player with rules. if you hard coded which characters are allowed to have which set of spells, you would run into trouble if a designer wanted to make a game mode where everyone gets the same set of spells, or the set of spells changes throughout the game, like Gun Game in Call of Duty.

so programmers should make things generic and flexible, while designers make things specific and challenging. programmers create as many new possibilities as they can, while designers limit these possibilities to create challenges and improve balance.

avatar image Douglas Lassance Apr 26 '16 at 12:42 AM

I understand what you mean, but I think that might depends on the actual game needs to. For instance I think in the game I am trying to design, it would actually be more maintenance if I had to manage a list of spells per character. Whereas by having a Magician class key on each Spell, I can set it to be available for Magician, Merlin or Gandalf. In other words, shared by all magicians or specific to one.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question