Exposing global instances in the editor

I want to define a set of Ability instances that can be referenced by Actors in multiple Levels. Level designers should be able to tweak the properties of each Ability and select them from drop-down of Ability-typed fields.

I can do it in code fairly easily by storing Ability instances on something referenced by the GameInstance object and then accessing them from within the Levels through C++ or Blueprints. However, I’m at a loss of how to expose them in the editor.

The Content Browser only contains classes rather than instances, so unless I make a subclass for every ability and treat them as singletons, they can’t be stored in the content browser.

One approach I tried was to make these Abilities Actors and create an AbilityDatabase Level which would contain Ability instances to be referenced. Then I assigned this as an always-loaded sub-level for actual Levels that references abilities. Now in the actual Levels, these Ability instances show up in the outliner and in the drop-down for fields of Ability type. However, whenever I try to assign a value for such a field to an Ability instance from the Database, the editor simply ignores my assignment. Is there no way to make cross-level references in the editor?

Another approach I considered was using a Struct for the Abilities and creating a DataTable, but it seems that there’s no way to create a typed input field referring to a DataTable; I still have to query the table in code. Plus the table editor is very limited: you can’t even assign references to assets, and are forced to export it to a CSV and edit that by copy-pasting IDs; this is obviously a nightmare.

Note that I’m using Abilities as an example, but I’m interested in a general solution. I’m aware of the WIP GameplayAbility system, but that doesn’t solve the general problem.

Well, this was silly. In my search of workarounds I missed a fundamental wrong assumption. The Content Browser can indeed store instances, and that is done using the Data Asset type. The bit that made it hard to discover is the fact that you have to create a class inheriting from UDataAsset before you can create these Data Asset objects; you cannot use a USTRUCT or an arbitrary UObject class. However, UDataAsset is not limited in any way relative to UObject; it can still contain UFUNCTIONs, be tagged as BlueprintType, etc.

Also, the fact that the doc in the editor tooltip for Data Asset says “Base class for a simple asset containing data” is also quite misleading.