这部分对于很多小项目,直接通过硬加载的方式就可以完成需求。资源的软加载的方式可以降低内存在某一瞬间的暴增,所以合理的设计资源的加载方式,在一定程度上可以优化项目。
硬加载方式
对象A引用对象B,导致对象A被加载时,B也被加载
- 直接属性
/** construction start sound stinger */
UPROPERTY(EditDefaultsOnly, Category=Mesh)
UStaticMesh* MeshData;
- 构造时引用
ConstructorHelpers::FObjectFinder<> 可以实现模型,贴图,文件,特效,材质等加载
该方法只能在构造中使用
static ConstructorHelpers::FObjectFinder<UStaticMesh> meshIns(
TEXT("StaticMesh'/Game/IndustryPropsPack6/Meshes/SM_Rack01.SM_Rack01'"));
if (meshIns.Object)
{
workMesh->SetStaticMesh(meshIns.Object);
}
FObjectFinder<> 和 FClassFinder 的区别
static ConstructorHelpers::FClassFinder<AActor> BP_MyActor(TEXT("Blueprint'/Game/BP_MyActor.BP_MyActor_C'"));
if (BP_MyActor.Succeeded())
{
BPMyActorClass = BP_MyActor.Class;
}
static ConstructorHelpers::FObjectFinder<UClass> bpClassFinder(TEXT("Blueprint'/Game/BP_MyActor.BP_MyActor_C'"));
if (bpClassFinder.Object)
{
UClass* bpClass = bpClassFinder.Object;
}
软加载方式
对象A通过间接机制(字符串形式的对象路径)引用B
- FStringAssetReferences
- TAssetPtr AssetPtr基本上就是一个封装了 FStringAssetReference 的 TWeakObjectPtr ,它使用一个特定的类作为模板,以便限制编辑器用户界面.
UPROPERTY(EditAnywhere)
UStaticMeshComponent* workMesh;
UPROPERTY(EditDefaultsOnly,Category="BulletType")
TAssetPtr<UStaticMesh> BaseMesh;
void ABackPackage::BeginPlay()
{
Super::BeginPlay();
workMesh->SetStaticMesh(GetLazyLoadedMesh());
}
// 这个方法要是在构造中调用,会出现给component 赋值出现失效的问题
UStaticMesh* ABackPackage::GetLazyLoadedMesh()
{
// 这个方法要是在构造中调用,会出现给component 赋值出现失效的问题
FStreamableManager* Streamble = new FStreamableManager();
// 检查资源是否已经准备好,可供访问
if (BaseMesh.IsPending())
{
// ToStringReference() 获得资源的引用路径
const FStringAssetReference& AssetRef = BaseMesh.ToStringReference();
// 资源的异步加载
BaseMesh = Cast<UStaticMesh>(Streamble->LoadSynchronous(AssetRef));
}
// 解除对资源的引用
return BaseMesh.Get();
}
同步加载方式和异步加载方式
LoadObject<>()
、StaticLoadObject()
,前两个方法以同步方式加载资产,这可能会导致帧速率突增
FStreamingManager
下的方法提供了异步加载的方式
参考上标题代码和我的另一篇博客文章UE4_Content目录资源检索以及异步载入资源
查找、加载对象
FindObject<>()
可以在 UObject 已加载或已创建时获得它。LoadObject<>()
可以在对象未加载时将其加载
关于StaticLoadClass 和 LoadClass
1 UMaterial* mt1 = LoadObject<UMaterial>(nullptr, TEXT("/Game/Map/Materials/grass.grass"));
2 UMaterial* mt2 = (UMaterial*)StaticLoadObject( T::StaticClass(), nullptr, TEXT("/Game/Map/Materials/grass.grass"));
1和2的两种方式写法是等价的
StaticLoadClass 应该是早期版本,Load应该是后来有的
LoadClass与LoadObject
LoadClass
- 加载蓝图时,要带后缀_C,一般用来加载蓝图资源
- 创建蓝图时,选择的父类名称作为类型
UClass* Test = LoadClass<AActor>(NULL, TEXT("Blueprint'/Game/Blueprints/Test_BP_C'"));
LoadObject
- 加载蓝图时,不需要加后缀
FObjectFinder FClassFinder
FObjectFinder 是对LoadObject的封装
FClassFinder 内部调用的是LoadObject
FindObject
// 通过名字查找
UClass* ActorRef = FindObject<UClass>(ANY_PACKAGE,*FString("AActor"));
//获取到UEnum
UEnum* EnumPtr=FindObject<UEnum>((UObject*)ANY_PACKAGE,*FString("EMyEnum"),true);
EnumPtr->GetEnumName((int32)0)); //获取到第0个枚举的名字
UClass 与 UObject的关系
UClass 与 UObject的关系
UObject
作用:为对象系统的基类
功能
创建子对象
对象Destroy相关事件处理
对象编辑相关事件
序列化
执行脚本
从config文件读取或保存成员变量配置
UClass
作用:定义一个数据结构描述类的信息,这个数据结构叫元数据。UClass 不仅仅可以描述C++,
也可以描述UBlueprint
两者可以相互获得对方的实例
UObject::StaticClass
UClass::GetDefaultObject