[c++]How to actually spawn actor after async load is complete

The question is kinda silly, but I fail to figure it out by myself.

I’m using [this tutorial][1].
Everything seems fine, but I don’t understand where to go from a point when I call method ResolveObject() on FStringAssetReference.
From this point, in tutorial parts of skeletal mesh are being attached one to other, but what I’m need to do is to load blueprints derived from c++ class AMyGameCharacter. And I don’t get what to do with this Resolved Object.

Before I was spawning blueprints preloaded with ConstructorHelpers::FClassFinder with GetWorld()->SpawnActor(UClass*, Location, Rotation, SpawinInfo), but now, when I try it returns either NULL, or memory access violation.
I’m guessing it is because whenever I try to get a Blueprint from Resolved Object I get some generic class and not the blueprint object I’ve loaded.

Anyway, simple question is this: how do I spawn object, that I have loaded from DataAsset? I don’ really get what to do, please help!

[1]: [TUTORIAL] C++ - Runtime Async Load Modular Character (Intermediate) - Community & Industry Discussion - Unreal Engine Forums(Intermediate=

Ok, I’ve posted this answer in tutorial thread, but just in case copying it here:

After Resolving Object I had to do the following:
Code:
( UClass*)(Cast(BlueprintAssetReference.ResolveObject()))->GeneratedClass;
This gives me desired class, that I then successfully spawn via WorldClass::SpawnActor() method

hey! I am trying exactly the same! But this doesnt work on packaged/standalone! Only in editor
Any idea?

No idea yet, sorry mate! I know about this issue, trying to follow few threads here on answerhub:

But since it’s not the first priority issue to me, I just put that on hold.
If you figure that out and have time, please point me in right direction.
Thanks!

Any news? ?

No luck yet. I’ve tried couple of things, even StaticLoad not working on packaged builds. ConstructorHelpers::FObjectFinder works, though. But it needs to be in constructor and I don’t like the idea of loading all assets on gamemode creation.
So I’m thingking of spawning some intermediate Actor, that would use FConstructorHelper in it’s constructor, pulling out string refenrence from gamemode, loading needed blueprint and returning loaded reference to gamemode, so gamemode would spawn it the end. Not sure that it would work though.

I think I’ve managed to do it in the end.
Will post a code in couple of hours.

So this is how I do it:

I am using 4.16.3 but I think it shall work the same in newer versions besides the fact that “TAssetSubclassOf” was renamed to “TSoftClassPtr” in 4.18.

Since 4.17 is the version marked in question - I will use “TAssetSubclassOf” version in the example below:
Please refer to A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums

TAssetSubclassOf allows us to reference a BlueprintAsset (that inherits some base class) so here is my H file:

FStreamableManager AssetLoader;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AsyncLoad)
TAssetSubclassOf<ABaseBodyPartsActor> m_BodyPartsPtr;

UFUNCTION(BlueprintCallable, Category = "SpawnAsyncLoadedParts")
ABaseBodyPartsActor* SpawnParts(FTransform transform);

UFUNCTION()
void LoadedAsstes();

and here is the CPP part :slight_smile:

//BeginPlay = start async load:

{

	Super::BeginPlay();

	if (m_BodyPartsPtr != nullptr)
	{
		FStringAssetReference AssetToLoad;
		AssetToLoad = m_BodyPartsPtr.ToStringReference();

		AssetLoader.RequestAsyncLoad(AssetToLoad, FStreamableDelegate::CreateUObject(this, &ACBaseUnitCharacter::LoadedAsstes), 1, true);
	}
...
}

    //Loaded assets callback - for me it is only 1 item so I left it as an empty implementation
    void ACBaseUnitCharacter::LoadedAsstes()
    {
    	if (m_BodyPartsPtr != nullptr)
    	{
    		if (m_BodyPartsPtr.IsValid())
    		{
    		}
    	}
    }
    
    //The spawn itself!
    ABaseBodyPartsActor* ACBaseUnitCharacter::SpawnParts(FTransform transform)
    {
    	if (m_BodyPartsPtr.IsValid() && GetWorld())
    	{
    		return GetWorld()->SpawnActor<ABaseBodyPartsActor>(m_BodyPartsPtr.Get(), transform);
    	}
    	else
    	{
    		return nullptr;
    	}
    }

Tested this code on both macOS and Windows10 within PIE and Shipment build - both works fine,

1 Like

It worked! Thank you.

My pleasure!

nice code btw :smiley: