UE4中资源加载资源的方式
发表于2018-02-26
在UNITY中,加载资源一般是通过Resources.Load(path).即可完成,该方法返回的是Object类型。如果你想要的是材质或者贴图等等,只要加个类型转换的关键字就可以了例如 as Material,则可以返回一个材质的引用……
在UE4中,加载资源的方式区别较大,为了不让初学者趟坑,下面就给大家介绍UE4中4种资源的加载方式。在UE4中,它的蓝图就大致等于UNTIY中的prefab.所以我们将资源弄成了蓝图的方式来进行加载。
第一种:如果该蓝图有C++类(或者说是从C++类创建的蓝图),直接进行加载
ATemp* spawnActor = GetWorld()->SpawnActor<ATemp>(ATemp::StaticClass());
所有的加载资源并创建到场景中的方式都离不开SpawnActor这一句代码。如果你的蓝图包含了C++类,那么可以直接访问类的StaticClass
剩下的加载方式均是单纯的加载蓝图,并没有对应的C++类
第二种:通过ConstructorHelpers来加载
static ConstructorHelpers::FClassFinder<AActor> bpClass(TEXT("/Game/BluePrint/TestObj")); if(bpClass.Class != NULL) { GetWorld()->SpawnActor(bpClass.Class); }
FClassFinder是一个结构体,其中的Class成员变量是TSubClassof<T>类型的。所以我们只需要SpawnActor(bpClass.Class)就可以生成我们要的东西了
但是值得一提的是该方法只能在类的构造函数中使用,如果在普通的逻辑代码中嵌套这份代码,很可能引起整个编译器的crash。以下是该代码的具体执行步骤
struct FClassFinder { TSubclassOf<T> Class; FClassFinder(const TCHAR* ClassToFind) { CheckIfIsInConstructor(ClassToFind); FString PathName(ClassToFind); StripObjectClass(PathName, true); Class = ConstructorHelpersInternal::FindOrLoadClass(PathName, T::StaticClass()); ValidateObject(*Class, PathName, *PathName); } bool Succeeded() { return !!*Class; } };
不难看出该方法在一开头的地方就先检查了是否在构造函数中。CheckIfIsInConstructor,如果不是的话可能会引起crash(具体原因不明)……然后通过路径去找到我们要加载的类,并返回给我们。另外一点,该变量必须是static的……
第三种:通过FStringAssetReference来加载
FStringAssetReference asset = "Blueprint'/Game/BluePrint/TestObj.TestObj'"; UObject* itemObj = asset.ResolveObject(); UBlueprint* gen = Cast<UBlueprint>(itemObj); if (gen != NULL) { AActor* spawnActor = GetWorld()->SpawnActor<AActor>(gen->GeneratedClass); }*/
FStringAssetReference类的作用主要是通过一个字符串,找到该字符串所对应的资源。或者通过给定的资源,找到该资源所对应的在项目中的路径,也就是前面所说的字符串
其中,asset.ResolveObject就是查找字符串对应的资源,返回一个UObejct,我们通过将其转化成UBlueprint类型然后再去的他的GenerateClass即可。
第四种:通过StaticLoadObject来加载
UObject* loadObj = StaticLoadObject(UBlueprint::StaticClass(), NULL, TEXT("Blueprint'/Game/BluePrint/TestObj.TestObj'")); if (loadObj != nullptr) { UBlueprint* ubp = Cast<UBlueprint>(loadObj); AActor* spawnActor = GetWorld()->SpawnActor<AActor>(ubp->GeneratedClass); UE_LOG(LogClass, Log, TEXT("Success")); }
原理的话几乎是和第三种是一样的,只是调用的方式不同而已,在这里就不再赘述了。
总结下来,第三种和第四种应该是最通用的。因为第一种要求有对应的蓝图C++类,而第二种又要求一定要是在构造函数中完成(不论是在谁的构造函数都可以,但该方法一定只能在构造函数中调用)