虚幻引擎基础入门(C++)

您所在的位置:网站首页 中国对沙特阵型的评价 虚幻引擎基础入门(C++)

虚幻引擎基础入门(C++)

2023-02-11 05:10| 来源: 网络整理| 查看: 265

虚幻引擎基础入门(C++) — 【资源加载 08】

文章目录 虚幻引擎基础入门(C++) — 【资源加载 08】前言一、直接属性引用二、间接属性引用三、同步加载和异步加载四、同步加载和异步加载总结

前言

在虚幻中我们需要处理的资源分为:类资源和非类资源。

资源/资产加载到内存中,我们操作需要通过引用来完成,引用分两类:

直接属性引用(硬性引用):直接引用 间接属性引用(软性引用):通过间接机制(如字符串形式的对象路径)来引用

加载方式分为:

同步加载(资源过大会导致游戏程序卡顿)

01.在加载运行线程中,阻塞线程的流程执行,将线程停止在当前加载逻辑中,加载完成后继续线程的执行逻辑操作 02.对于加载小资源可以保证资源的不为空,但是加载大资源将导致调用线程卡顿

异步加载

在加载线程中,不阻塞当前线程逻辑加载资源,加载器本身具备线程进行资源加载 比同步加载更加灵活,但维护成本较高,资源加载成功后需要进行回调通知,以完成整个加载流程

一、直接属性引用 编辑器直接加载

通过使用属性 UPROPERTY 宏标记,将资产对象指针暴露到编辑器面板,从而直接从编辑器面板拾取资产

TSubClassOf

01.是提供UClass的安全模板类,可以快速构建某种类型对象数据 02.但只能选取模版类型或继承自模版类型的类 / 蓝图

//1.引用类资源 //① UClass类:暴露到蓝图中,直接拾取任意类资源(用指针) UPROPERTY(EditAnyWhere, BlueprintReadWrite) UClass* CharacterClass; //② TSubclassOf:只能用来拾取 AMyActor 类或其子类(用包裹)(记得加头文件) UPROPERTY(EditAnyWhere, BlueprintReadWrite) TSubclassOf MyActor; MyActor.GetClass(); //获取UClass指针 //2.引用非类资源 UPROPERTY(EditAnyWhere, BlueprintReadWrite) USoundBase* Sound; //拾取音频资源 //拾取音频还可以用:USoundCue(加头文件#include) UPROPERTY(EditAnyWhere, BlueprintReadWrite) UStaticMesh* Mesh; //拾取静态网格体 UPROPERTY(EditAnyWhere, BlueprintReadWrite) UStaticMeshComponent* Mesh; //静态网格体组件(装载资产的组件) UPROPERTY(EditAnyWhere, BlueprintReadWrite) USkeletalMesh* SMesh; //拾取骨骼网格体 //3.加载类资源和非类资源 //UObject类 UPROPERTY(EditAnyWhere, BlueprintReadWrite) UObject* Object;

在这里插入图片描述

构造函数加载

- 借助构造函数资产加载类进行资源引用 - ConstructorHelpers可以进行类引用,源资源引用 - ConstructorHelpers 只能在构造函数中使用,GameInstance中是 Init 函数(需要重载)

常用的资源加载分类:

FClassFinder:加载创建后的蓝图对象

ConstructorHelpers::FClassFinder(TEXT("/Game/Flappybird/Blueprints/BP_Bird")).Class;//返回数据类型是TSubClassof //使用路径拾取蓝图对象(要加_C) ConstructorHelpers::FClassFinder UnitSelector(TEXT(“Blueprint‘/Game/Blueprints/MyBlueprint.MyBlueprint_C’”));//下划线C必须要加

FObjectFinder:加载各种资源(如音频,图片,材质,静态网格)

ConstructorHelpers::FObjectFinder BarFillObj(TEXT("/Game/UI/HUD/BarFill")); BarFillTexture = BarFillObj.Object; //将获取的数据内容指针保存

注意: 操作路径前加入 /Game/ 前缀 加载蓝图类模版对象时,需要加注“_C” 加载失败或是未找到资源,对象内的资产属性为null

查找加载

1>在只知道目标资源路径的基础上,进行运行时态的资源加载

2>资源加载可能会失败或是无效,所以需要对操作的结果进行判定

LoadClass:加载类资产,可放在任何地方加装 , 返回UClass指针,可用TSubclassOf来接

TSubclassOf Player1 = LoadClass(NULL, TEXT(“Blueprint’/Game/BP/BP_Actor.BP_Actor_C’”));

LoadObject:加载类资源 + 非类资产,返回该类的指针

AMyActor* Player2 = LoadObject(NULL, TEXT(“Blueprint’/Game/BP/BP_Actor.BP_Actor_C’”));

查找加载 此处的 “文件路径” 是复制绝对路径 在这里插入图片描述 二、间接属性引用 FSoftObjectPath

是一个简单的结构体,使用一个字符串包含资源的完整名称

可以在编辑器中拾取资源(与直接属性引用相同),但没有把资源加载到内存(资源的加载需要通过额外的代码编写完成)

对于资源的拾取并没有特定的要求,所有能够被序列化的资源均能被拾取(类资源,非类资源)

FSoftClassPath 仅拾取类资源链接 //(在.h文件中) //间接属性引用 //1.FSoftClassPath,用于拾取类资源的链接 UPROPERTY(EditAnywhere) FSoftClassPath CharacterPath; //2.FSoftObjectPath:(类资源 + 非类资源)暴露到蓝图中拾取的是一个链接,不会进行资源加载 UPROPERTY(EditAnyWhere) FSoftObjectPath SoundPath; 三、同步加载和异步加载 同步加载(加载大资源将导致调用线程卡顿)异步加载(资源加载成功后需要进行回调通知)

FSreamableManager 构建异步处理逻辑,创建在全局游戏的单例对象中,结合FSoftObjectPath进行加载

//(在UECCharacter.h文件中) #include //资源加载器头文件引入 UCLASS(config=Game) class AUECCharacter : public ACharacter { public: //1.同步加载 //加载播放音效资源 void LoadPlaySound(); //2.异步加载 //① 声明资源加载器(构建为栈对象,需引入头文件,不要构建为堆对象) FStreamableManager LoadStream; //② 回调通知函数 void LoadCallBack(); }; /(在UECCharacter.cpp文件中) #include //播放音频头文件引入 void AUECCharacter::LoadPlaySound() { if (!SoundPath.IsValid()) //判断资产链接是否有效 { //如果资产链接无效,则直接设置资产路径(可以用来替代细节面板中的引用) SoundPath.SetPath(TEXT("SoundCue'/Game/StarterContent/Audio/Collapse_Cue.Collapse_Cue'")); } //尝试加载资源 UObject*Source = SoundPath.TryLoad(); //1.同步加载(会阻塞线程) UObject* Source = LoadStream.LoadSynchronous(SoundPath); //2.异步加载 //① 请求加载,并绑定回调函数(资源,单播) LoadStream.RequestAsyncLoad(SoundPath,FStreamableDelegate::CreateUObject(this,&AUECCharacter::LoadCallBack)); } //② 回调函数调用(表明异步加载完成) void AUECCharacter::LoadCallBack() { //类型转换Cast //SoundPath.ResolveObject():获取异步加载好的资源引用 USoundBase* Sound = Cast(SoundPath.ResolveObject()); if (Sound) { //播放音效 UGameplayStatics::PlaySound2D(GetWorld(), Sound); } } 四、同步加载和异步加载

TSoftObjectPtr和TSoftClassPtr

TSoftObjectPtr和TSoftClassPtr也分为同步加载与异步加载 UPROPERTY(EditAnywhere) TSoftObjectPtr SoftMesh; UPROPERTY(EditAnywhere) TSoftClassPtr SoftTestActor; TSoftObjectPtr

同步加载

//(.h 文件) UPROPERTY(EditAnywhere) TSoftObjectPtr SoftMesh; // 构建为栈对象,需要引入头文件,不要构建为堆对象 // #include "Engine/StreamableManager.h" FStreamableManager m_Streamable; //(.cpp文件) // 可以转换为FSoftObjectPath对象 SoftMesh.ToSoftObjectPath(); // 同步加载 UObject* Source = m_Streamable.LoadSynchronous(SoftMesh); UStaticMesh* Mesh = Cast(Source); if (Mesh) { UKismetSystemLibrary::PrintString(this, TEXT("加载成功!")); }

异步加载

//(.h文件) // 异步加载回调函数 void LoadSourceCallback(); //(.cpp文件) // 异步加载 //需要在初始化函数中绑定回调函数,然后实现回调函数 m_Streamable.RequestAsyncLoad(SoftMesh.ToSoftObjectPath(), FStreamableDelegate::CreateUObject(this, &UTestGameInstance::LoadSourceCallback)); TSoftClassPtr

同步加载

//(.h文件) UPROPERTY(EditAnywhere) TSoftObjectPtr SoftMesh; // 构建为栈对象,需要引入头文件,不要构建为堆对象 // #include "Engine/StreamableManager.h" FStreamableManager m_Streamable; //(.cpp文件) // 同步加载 TSubclassOf TestActorClass = m_Streamable.LoadSynchronous(SoftTestActor); if (TestActorClass) { GetWorld()->SpawnActor(TestActorClass); } //(.cpp文件) // 异步加载 m_Streamable.RequestAsyncLoad(SoftTestActor.ToSoftObjectPath(), FStreamableDelegate::CreateUObject(this, &UTestGameInstance::LoadSourceCallback)); //回调函数实现 void UTestGameInstance::LoadSourceCallback() { // 此函数调用,则表明异步加载完成 UClass* TestActorClass = SoftTestActor.Get(); if (TestActorClass) { GetWorld()->SpawnActor(TestActorClass); } } 总结

以上就是今天要讲的内容,本文仅仅简单介绍了虚幻引擎中资源加载的使用。

如有帮助给个关注吧!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3