Can you walk me through creating a Primary Asset?

I’m currently trying to create a couple Primary Assets but the [documentation][1] leaves much to be desired.
In order for my asset to become a Primary Asset, it needs to override GetPrimaryAssetId. I do this as follows:

MyActor.H

virtual FPrimaryAssetId GetPrimaryAssetId() const override;

MyActor.cpp

FPrimaryAssetId AMyActor::GetPrimaryAssetId() const
{
	FName primaryAssetType = GetClass()->GetFName();
    FName primaryAssetName = GetOutermost()->GetFName();
    return FPrimaryAssetId(primaryAssetType, primaryAssetName);
}

Despite the documentation saying that I need to return a a valid FPrimaryAssetId, it doesn’t exactly explain what a valid FPrimaryAssetId is. So I went and took a look at how UWorld did it in World.cpp and UPrimaryDataAsset in DataAsset.cpp. It seemed straight forward and I added the following settings under the Asset Manager:

292331-capture.png

but when I try to print a list of Primary Asset Ids for MyActors, the list is empty:

I’m not exactly sure what I am doing wrong. Any help is much appreciated!

2 Likes

I don’t need an answer. After spending 8+ hours trying to figure out what primary assets actually are, I couldn’t. However, I can just override the asset manager and do a lot less of what the process of creating a primary asset and do way more with it. I really don’t get why this exists or why it’s so restrictive.

For those who find this post in search of understanding on how to create Primary Assets, Mattlauk’s solution was almost correct in the sense that just his GetPrimaryAssetId() function messed up the type.

In reality, if you decide to create a Primary Asset Type in the Project Settings, whatever you write in the Primary Asset Type field in the settings you should use in your C++ function.

In this scenario using the original poster’s Primary Asset Type, which is MyActors, as configured in his Project Settings, we can refactor the C++ function to use said type correctly:

FPrimaryAssetId AMyActor::GetPrimaryAssetId() const
{
	FName primaryAssetType = "MyActors";
	FName primaryAssetName = FPackageName::GetShortFName(GetPackage()->GetFName()); 
	return FPrimaryAssetId(primaryAssetType, primaryAssetName);
}

GetOutermost(), which was used in the original code, is an obsolete version of the newer GetPackage() so I used GetPackage() in the refactored function.
(I also added FPackageName::GetShortFName() as I noticed that the Asset Manager internally uses it to determine Primary Asset Ids when that is configured in the Project Settings. It is supposed to remove the path part of GetFName() and only keep the object name, aka it removes the /Game/Folder/ from /Game/Folder/MyActor so your Primary Asset Ids will look like MyActors:MyActor instead of MyActors:/Game/Folder/MyActor.)

That is all that needs to be changed for Mattaluk’s initial solution to actually work, but you can always go one step further by defining a more specific search directory than /Game, using a native class as the base class if you wish or even extending UAssetManager for your own needs.