TSoftObjectPtr referenced assets not packaged

Hello,

So I am pretty sure this is an engine bug, but I wanted to make sure I’m not doing somthing wrong before creating a bug report. Basically the issue seems to be that an asset referenced via TSoftObjectPtr is not included in a packaged build if it is set via C++ in the constructor, it does however work when the pointer is set through the defaults panel of a child blueprint class.

This is what my code looks like:

UPROPERTY(EditAnywhere)
TSoftObjectPtr<USoundBase> SoundAsset;

ASomeActorClass::ASomeActorClass()
{
SoundAsset = FSoftObjectPath("/Game/Sounds/MySoundAsset");
}

In a packaged build the string path in the reference is set, however trying to load it results in this warning in the log:

LogStreaming: Error: Couldn't find file for package /Game/Sounds/MySoundAsset requested by async loading code. NameToLoad: /Game/Sounds/MySoundAsset

The issue is not that the pointer isn’t a UPROPERTY, neither that I’m referencing an asset that does not exist outside of editor builds. It does work when I assign the asset via the defaults panel in the child blueprint class, it also works when I use a hard pointer in C++.

Any thoughts?

You will need to add the directory to be cooked in the DefaultGame.ini (can be done in Project Settings). You will need to add the folder that the asset is in:

+DirectoriesToAlwaysCook=(Path=“Sounds”)

The code is not scanned for any references so according to the Engine, the assets are not references anywhere so you will need to manually do it.

I do know that I could set certain directories to always cook, however that is more of a workaround, prone to errors when forgetting to add a folder and will also include assets that are not referenced at all.
I don’t know exactly how the cooking process works, if you know more about it I would be glad if you could share it. As far as I know you can reference assets purely in C++ UObject derived classes, for example if I load an asset via ConstructorHelpers::FObjectFinder and assign it to a UPROPERTY hard pointer it will be cooked. But this soft pointer isn’t even purely in a C++ class, I made a child blueprint class where I can see the correct asset assigned in the details panel. The blueprint itself is cooked, but not the asset. If I don’t set the asset reference in C++ and instead select it from the details panel, it will be cooked.

I made a little example project to confirm the bug, basically when you PIE you will see two particle systems, when you run a packaged build you will only see one:
https://drive.google.com/file/d/19ziTy5qy9YkuRiYqrNkEEd6fT4n24dBO/view?usp=sharing

I eventually figured this out after hours of searching through the engine code and just noticed this thread was still open. The solution ended up being to call FSoftObjectPath::PostLoadPath after the reference was initialized in the editor, which is done automatically when the asset is assigned through a blueprint.

SoundAsset = FSoftObjectPath("/Game/Sounds/MySoundAsset");
	SoundAsset .ToSoftObjectPath().PostLoadPath(nullptr);
2 Likes