目录 | C++创建蓝图函数库LoadObject 参数利用蓝图泛型代码Demo |
---|
在虚幻运行时,动态地选择资源文件(资产/Asset),读取并导入到UE系统,有若干种方法,比如importFileAsTexture2D可以读取图片文件封装成Texture对象,如果要读取任意的uasset文件,找了一大圈发现只有LoadObject方法能实现。UAsset是一种可以序列化的UObject对象,包括所有常用的类型(网格体、材质、纹理...),序列化的结果就是uasset/umap文件。所以LoadObject方法是一种通用的方法,用来动态导入静态资源。
为了创建静态方法暴露给蓝图使用,最好的办法是继承UBlueprintFunctionLibrary,同时使用static修饰函数,否则必须实例化才能使用。
C++泛型机制通过template模板动态地调整接口类型,蓝图也有类似的机制:DeterminesOutputType,利用这个宏可以根据某个参数的类型改变返回值的类型。有了泛型,就可以写一个通用的蓝图节点,不用为每一种资产类型单独写一个节点。除此之外,我们需要一个特殊的模板类TSubclassOf来让蓝图出现下拉选框,TSubclassOf的选择对象是UClass反射类,选择的范围是某个指定类的所有子类。由于本次实验主要需要StaticMesh和Texture这两个子类,我们选择UStreamableRenderAsset作为他们俩的公共父类。这个类的继承层次如下:
UObjectBase
----UObjectBaseUtility
--------UObject
------------UStreamableRenderAsset
----------------USkeletalMesh
----------------UStaticMesh
----------------UTexture
利用UFUNCTION暴露一个静态方法LoadAssetFromPath,总共2个参数:Path是资产的相对路径,TargetClass是资产的类型。函数输出对应类型的资产。
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
// must be last #include
#include "AssetLoader.generated.h"
UCLASS()
class CPPTEST_API UAssetLoader : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, meta = (DisplayName = "LoadAssetFromPath", DeterminesOutputType = "TargetClass"), Category = "LoadAsset")
static UObject* LoadAssetFromPath(const FString& Path, TSubclassOfTargetClass) {
UObject* loadedObject = LoadObject( NULL, *(Path));
// will be converted to TargetClass automatically
return loadedObject;
};
};
加载一个static mesh,并赋给某个static mesh component:
加载一个texture,并赋给一个动态材质实例(MID):