Load Object of AActor Returns Nullptr

I’ve got a class that is a subclass of a subclass of AActor. I want to be able to spawn a BP derived version of the class from a different class. However the AActor* that I assign to the LoadObject is always nullptr.

This is my code:

fireballProjectile = LoadObject<AActor>(nullptr, TEXT("/Script/Engine.Blueprint'/Game/Blueprints/fireball1.fireball1'"));

fireball1 is a BP derived from ProjectileBase.h which is derived from AActor.h. Any ideas as to why it fails to load?

In the asset there’s a Blueprint and a Class (BlueprintGeneratedClass), there is no actor.
Blueprint is editor-only data that exists for editing (scene view, graphs, compiling…).
Class/BlueprintGeneratedClass is what you use to spawn actors, via World->SpawnActor method.
The naming convention is always the same :

Package   = /Game/Blueprints/fireball1
Blueprint = /Game/Blueprints/fireball1.fireball1
Class     = /Game/Blueprints/fireball1.fireball1_C
CDO       = /Game/Blueprints/fireball1.Default__fireball1_C

Note that you probably never want to load the Blueprint itself, unless you are working on editor utility tools.
So what you want is probably something like this :

UClass* ProjectileClass = LoadClass<UClass>(nullptr, "/Game/Blueprints/fireball1.fireball1_C");

fireballProjectile = GetWorld()->SpawnActor<AProjectileBase>(ProjectileClass, Location, Rotation);

Now, while it should work, this is not the recommended way to do it.
Loading assets via string references like this is not only prone to error, but also doesn’t tell the packager that this asset is needed by the game.
If you don’t have a direct reference to that asset somewhere else then it won’t be packaged in your game and won’t work in your shipping build.

There are two ways to go about this.
Method 1 :

  • your C++ class responsible for this code must have BP subclass(es). For example let’s say this is AWeaponBase, and this is the code to spawn the projectile. All your actual weapons are gonna be blueprints subclasses of this.

  • In AWeaponBase header, add a class property like this

UPROPERTY(EditAnywhere)
TSubclassOf<AProjectileBase> ProjectileClass;
  • In C++, use that variable instead of loading the class manually
fireballProjectile = GetWorld()->SpawnActor<AProjectileBase>(ProjectileClass, Location, Rotation);
  • In your weapons blueprints, fill in that ProjectileClass property
    image

Method 2 :

  • If for some odd reason you don’t want to make a BP subclass of this, ie. this is the final class and it is C++ only

  • You must load the class in the constructor, so you kinda have to add a variable to hold the class reference anyways, just like method 1

UPROPERTY()
UClass* ProjectileClass;
  • In the constructor, load the class using FClassFinder utility
AWeaponBase::AWeaponBase()
{
    static ConstructorHelpers::FClassFinder ProjectileAsset(TEXT("/Game/Blueprints/fireball1"));
    if (ProjectileAsset.Succeeded())
        ProjectileClass = ProjectileAsset.Class;
}
1 Like

Wow, what a morning to wake up to such a well written answer!

  • If for some odd reason you don’t want to make a BP subclass of this, ie. this is the final class and it is C++ only

I read in a forum on here that BPs are noticeably slower than C++ classes, so I am actually inclined to make C++ only classes when a “template” is not needed. I don’t know if that post was for ue4 or ue5 so it may have been an outdated post though.

This worked though.
Thank you, for your help!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.