TAssetPtr comes up as NULL when set from Blueprints

I have a TAssetPtr in my class like this:

class ANPC : public ACharacter
{
    ///...
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = NPCMessage)
    TAssetPtr<class UTexture2D> Face;
}	

In blueprints, I can see my Face variable show up, and I can assign a Texture2D to it… but every time I check the NPC’s TAssetPtr.Get() in render, it always comes up NULL.

I think it is because of TAssetPtr being a weak pointer. I tried using a TSubobjectPtr but that becomes BlueprintReadOnly…

Is there a way to make the TAssetPtr retain the reference it got previously in blueprints and not become NULL?

Edit: This problem doesn’t happen when the texture is first imported into UE4 editor. if I import a texture, assign it to Face in blueprints, and run, then the tex isn’t NULL then.

But if the texture was already loaded into the editor before, and I try to launch the game, the tex is NULL then.

  • I just found if i hit “Reimport” on the image, it seems to work

The only way I could solve this was to not use a TAssetPtr. in my code, I just use a regular C++ pointer type now:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = NPCMessage)
UTexture2D* Face;

TAssetPtr.Get() is always going to return NULL until the asset is actually loaded.
In order to load the object you’ll need to have an active FStreamableManager somewhere you can access and do something like this:

if (Face.IsPending()){
  FStreamableManager& AssetMgr = GetStreamableMgr();
  const FStringAssetReference& AssetRef = Face.ToStringReference();
  Face = Cast<UTexture2D>(AssetMgr.SynchronousLoad(AssetRef));

}

After loading you can retrieve the UTexture2D pointer by calling Face.Get();

The above is an example of a synchronous, blocking load. If you want to do asynchronous loading you can call RequestAsyncLoad, which you can pass a delegate to be fired after the load is complete.

See here:

and here: