How to get asset by string reference?

I would like to create a Blueprint node using C++ that I can pass a string reference to an asset (specifically for Materials and Media Players) that will return the asset reference itself.

For example, if I pass this string (for Material):

Material'/Game/Movies/Alan_Senauke_001_Tex_Mat.Alan_Senauke_001_Tex_Mat'

or this string (for Media Player):

MediaPlayer'/Game/Movies/Alan_Senauke_001.Alan_Senauke_001'

Then it would return a reference to the Material, or the Media Player, respectively.

This is for initialization of lots of objects at the start of the game. I was attempting to do it with a struct and Data Table, but Data Tables seem to be very unstable and are crashing the project repeatedly and inconsistently.

If I can create a node like this I can avoid Data Tables altogether.

Does anyone know if this is possible?

EDIT:

I’ve been trying 's suggestion, but it’s not showing up in BP:

I’ve tried using the code you’ve suggested, but for some reason it’s not appearing in Blueprint. Here is the full code for what I’m trying. I’m including another function here in the code, because that one is showing up in Blueprint.

MyBlueprintFunctionLibrary.h

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"

/**
 * 
 */
UCLASS()
class ASSETLOADER_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
    // Load a material from the corresponding path
    UFUNCTION(BlueprintCallable, Category = "Asset Loading")
    UMaterial * LoadMaterialReference(const FString& materialPath);
	
    UFUNCTION(BlueprintCallable, Category = "Asset Loading")
    static bool SaveStringTextToFile(FString fileName, FString SaveText, bool AllowOverWriting);
};

MyBlueprintFunctionLibrary.cpp

#include "AssetLoader.h"
#include "MyBlueprintFunctionLibrary.h"

UMaterial * UMyBlueprintFunctionLibrary::LoadMaterialReference(const FString& materialPath)
{
    FStringAssetReference assetRef(materialPath);
    return Cast<UMaterial>(assetRef.TryLoad());
}

bool UMyBlueprintFunctionLibrary::SaveStringTextToFile(FString fileName, FString SaveText, bool AllowOverWriting)
{
    FString path;
    path = FPaths::GameDir();
    path += "/User_Playlists";
    
    if (!FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*path))
    {
        FPlatformFileManager::Get().GetPlatformFile().CreateDirectory(*path);
        if (!FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*path))
        {
            return false;
        }
    }
    
    path += "/";
    path += fileName;
    path += ".playlist";
    
    if (!AllowOverWriting)
    {
        if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*path))
        {
            return false;
        }
    }
    
    return FFileHelper::SaveStringToFile(SaveText, *path);
}

Here is how it looks in BP after compiling:

85874-screen+shot+2016-04-08+at+13.21.43.png

Any idea why it doesn’t show up?

Hi localstarlight,

I’ve not tried this yet – I’ve always found the Data Tables and TAssetPtr’s to do the trick nicely. If you want to stick with that approach, I’d be happy to help as best I can.

That said, I think the style you’re thinking of should be possible. Looking at the docs on the TAssetPtr’s shows that they are apparently just wrappers on FStringAssetReference’s. You can see their documentation here:
https://docs.unrealengine.com/latest/INT/API/Runtime/CoreUObject/Misc/FStringAssetReference/index.html

It looks like you can create an FStringAssetReference from an FString like you have. From there, I’d think you could use TryLoad() to actually load the asset. Then it would just be a matter of casting it to the proper type. Maybe something like this would do the trick?

*.h

public:
    // Load a material from the corresponding path
    UFUNCTION(BlueprintCallable, Category = "Asset Loading")
    UMaterial * LoadMaterialReference(const FString& materialPath);

*.cpp

UMaterial * AssetLoader::LoadMaterialReference(const FString& materialPath)
{
    FStringAssetReference assetRef(materialPath);
    return Cast<UMaterial>(assetRef.TryLoad());
}

(I tried to put my response to your answer here but it didn’t work). I’ve tried what you suggested, but it’s not showing up in Blueprint – I’ve edited my question, see above. Any idea why it doesn’t show up? Thanks!

I added ‘static’ before UMaterial in the header file and now it works! Thanks so much!
I don’t understand C++ really, so not sure why the ‘static’ was needed, but there you go.
Thanks so much for your help.

However, when I try to create the same function but for Media Players, it produces this error: Unrecognized type ‘UMediaPlayer’ - type must be a UCLASS, USTRUCT or UENUM
Surely UMediaPlayer is a UClass?

Figured it out! Needed to add #include “MediaPlayer.h” to the header, and MediaAssets to the Build.cs file, as explained in the answer on this page: Quick Question: UMediaplayer is undefined - Pipeline & Plugins - Epic Developer Community Forums

can someone post the full code?
thanks