智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...
随笔 - 991, 文章 - 0, 评论 - 27, 阅读 - 341万

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

UE4:四种加载资源的方式

Posted on   Bill Yuan  阅读(11554)  评论(0编辑  收藏  举报

转自:https://blog.csdn.net/zhangxsv123/article/details/79707686

第一种: 如果该蓝图有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++类,而第二种又要求一定要是在构造函数中完成(不论是在谁的构造函数都可以,但该方法一定只能在构造函数中调用)...

(评论功能已被禁用)
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2013-08-22 CCLabelTTF、CCLabelAtlas和CCLabelBMFont的区别
点击右上角即可分享
微信分享提示