Download

Need code snippet: Create new actor from uproperty actor pointer (C++)

Let’s say I have custom actor class named AMyActor.

In one of my objects I have:



UPROPERTY(EditAnywhere, BlueprintReadOnly)
TSubclassOf<AMyActor> actorPrefab;


Where actorPrefab points at one of the blueprints derived from AMyActor which sits in content browser, not in the scene.

So, during runtime I want to spawn a clone of whatever blueprint or class actorPrefab is pointing at.

The problem is that calling



GetWorld()->SpawnActor(actorPrefab->GetClass(),...)


Doesn’t work, and prints an error (“SpawnActor failed because BlueprintGeneratedClass is not an actor class”).

Now, all the articles online only mention how to spawn objects using hardcoded path, FStaticObjectFinder and FStringAssetReference.
There’s also TAssetPtr which require you to babysit object loading.

How do I spawn thing via TSubclassOf pointer? basically, I want the same kind of workflow as I had in unity, where you specify base class you want to reference, drag content browser asset to it, then clone it at runtime to make a copy.

This does not do what you assumed it does and intended to do. actorPrefab->GetClass() will call the GetClass() method on the UClass currently assigned to the TSubclassOf<> variable, the class of a blueprint class is BlueprintGeneratedClass. To retrieve the actual UClass (actor class) assigned simply use “*actorPrefab”.

Thanks for the response.

Would you mind explaining the logic here? If you have the time.

Usually (in C++) templated wrapper that stores pointer to something redirects calls to contents via operator-> and operator* would be doing the same thing.
You say that in this case -> redirects to something that is not the class specified as template parameter? Why?

It should be clear if you look at the definition of the TSubclassOf template. What it holds is actually a UClass*, not an instance of AMyActor. It simply uses the tempate argument to do some type checks (both compile time and runtime) for safety, but essentially a TSubclassOf is just a fancy UClass*.

So, given that it represents a UClass and not an instance, you don’t want to be calling GetClass on it.

Ah, now it clicked. I got it.

Basically, if in unity prefab is a “sample object”(that acts like object instance) that needs to be duplicated, in UE4 blueprint is treated as separate object class and reference to blueprint essentially just marks instance of which class you’d like to construct. Interesting.

Thanks for explanation, problem solved.