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

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


上一篇:虚幻引擎基础入门(C++) — 【宏定义 07】

前言

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

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

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

  3. 加载方式分为:

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

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

    异步加载

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


一、直接属性引用

  1. 编辑器直接加载

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

  1. TSubClassOf

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

	//1.引用类资源
    //① UClass类:暴露到蓝图中,直接拾取任意类资源(用指针)
    UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    UClass* CharacterClass;
 

    //② TSubclassOf:只能用来拾取 AMyActor 类或其子类(用<>包裹)(记得加头文件)
    UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    TSubclassOf<AMyActor> MyActor;
    MyActor.GetClass();  //获取UClass指针
//2.引用非类资源
	 UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    USoundBase* Sound;  //拾取音频资源
    //拾取音频还可以用:USoundCue(加头文件#include<Sound/USoundCue.h>)

    UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    UStaticMesh* Mesh;  //拾取静态网格体

    UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    UStaticMeshComponent* Mesh;  //静态网格体组件(装载资产的组件)

    UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    USkeletalMesh* SMesh;  //拾取骨骼网格体
 //3.加载类资源和非类资源
	 //UObject类
    UPROPERTY(EditAnyWhere, BlueprintReadWrite)
    UObject* Object;

在这里插入图片描述

  1. 构造函数加载

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

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

ConstructorHelpers::FClassFinder<APawn>(TEXT("/Game/Flappybird/Blueprints/BP_Bird")).Class;//返回数据类型是TSubClassof

//使用路径拾取蓝图对象(要加_C)
ConstructorHelpers::FClassFinder<AActor> UnitSelector(TEXT(“Blueprint‘/Game/Blueprints/MyBlueprint.MyBlueprint_C’”));//下划线C必须要加

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

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

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

  1. 查找加载

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’”));

  1. 查找加载
    此处的 “文件路径” 是复制绝对路径
    在这里插入图片描述

二、间接属性引用

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

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

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

  1. FSoftClassPath
  • 仅拾取类资源链接
//(在.h文件中)
//间接属性引用

//1.FSoftClassPath,用于拾取类资源的链接
    UPROPERTY(EditAnywhere)
    FSoftClassPath CharacterPath;


    //2.FSoftObjectPath:(类资源 + 非类资源)暴露到蓝图中拾取的是一个链接,不会进行资源加载
    UPROPERTY(EditAnyWhere)
    FSoftObjectPath SoundPath;

三、同步加载和异步加载

  1. 同步加载(加载大资源将导致调用线程卡顿)
  2. 异步加载(资源加载成功后需要进行回调通知)

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

//(在UECCharacter.h文件中)

#include <Engine/StreamableManager.h>  //资源加载器头文件引入

UCLASS(config=Game)
class AUECCharacter : public ACharacter
{
public:
    //1.同步加载
    //加载播放音效资源
    void LoadPlaySound();
    //2.异步加载
    //① 声明资源加载器(构建为栈对象,需引入头文件,不要构建为堆对象)
    FStreamableManager LoadStream;

    //② 回调通知函数
    void LoadCallBack();
};

/(在UECCharacter.cpp文件中)

#include <Kismet/GameplayStatics.h>  //播放音频头文件引入

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<USoundBase>(SoundPath.ResolveObject());

    if (Sound)
    {
        //播放音效
        UGameplayStatics::PlaySound2D(GetWorld(), Sound);
    }
}

四、同步加载和异步加载

TSoftObjectPtr和TSoftClassPtr

  • TSoftObjectPtr和TSoftClassPtr也分为同步加载与异步加载
UPROPERTY(EditAnywhere)
TSoftObjectPtr<class UStaticMesh> SoftMesh;
UPROPERTY(EditAnywhere)
TSoftClassPtr<class ATestActor> SoftTestActor;
  • TSoftObjectPtr

同步加载

//(.h 文件)

UPROPERTY(EditAnywhere)
TSoftObjectPtr<class UStaticMesh> SoftMesh;
// 构建为栈对象,需要引入头文件,不要构建为堆对象
// #include "Engine/StreamableManager.h"
FStreamableManager m_Streamable;

//(.cpp文件)

// 可以转换为FSoftObjectPath对象
SoftMesh.ToSoftObjectPath();

// 同步加载
UObject* Source = m_Streamable.LoadSynchronous(SoftMesh);
UStaticMesh* Mesh = Cast<UStaticMesh>(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<class UStaticMesh> SoftMesh;
// 构建为栈对象,需要引入头文件,不要构建为堆对象
// #include "Engine/StreamableManager.h"
FStreamableManager m_Streamable;

//(.cpp文件)

// 同步加载
TSubclassOf<ATestActor> TestActorClass = m_Streamable.LoadSynchronous(SoftTestActor);
if (TestActorClass) 
{
    GetWorld()->SpawnActor<ATestActor>(TestActorClass);
}

//(.cpp文件)

// 异步加载
m_Streamable.RequestAsyncLoad(SoftTestActor.ToSoftObjectPath(), FStreamableDelegate::CreateUObject(this, &UTestGameInstance::LoadSourceCallback));

//回调函数实现
void UTestGameInstance::LoadSourceCallback() {
// 此函数调用,则表明异步加载完成
UClass* TestActorClass = SoftTestActor.Get();
    if (TestActorClass) 
    {
        GetWorld()->SpawnActor<ATestActor>(TestActorClass);
    }
}

总结

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

如有帮助给个关注吧!

下一篇:虚幻引擎基础入门(C++) — 【代理说明 09】

Epic Games今天宣布,正式发布“虚幻引擎4”(Unreal Engine 4/UE4),相关所有资源也一并放出。# h9 u6 O( p! y& D) q4 K7 P9 ~# N   只要每个月花19美元,你就能到全部资源,包括拿过来就能用的虚幻编辑器(Unreal Editor),GitHub上的完整C++源代码(支持微软Visual Studio/苹果Xcode),还有完整的生态系统:论坛、维基、问答、协作。8 t8 q& _* ?7 K. D) S6 W 一大波新游戏要来了 虚幻4引擎正式发布, s! f+ v' w9 M j3 y: ^   而在虚幻引擎4游戏的销售中,Epic将抽取5%的毛收入提升,也就是你的游戏赚了100万美元,就要交给Epic 5万美元。   回到技术方面,Epic号称虚幻引擎4是他们多年来心血的结晶,而且现在只是第一版,才刚刚开始。C++代码里你可以看到大量的创新,比如说支持虚拟立体偷窥Oculus VR,支持Linux操作系统,以及支持Valve SteamWorks、StreamBox,而且还可以通过HTML5在网页浏览器内开发游戏(页游)。   平台支持PC、PS4、Xbox One、iOS、Google等等。   虚幻引擎4基于DirectX 11,拥有新的材料流水线、蓝图视觉化脚本、直观蓝图调试、内容浏览器、人物动画、Matinee影院级工具集、全新地形和植被、后期处理效果、热重载(Hot Reload)、模拟与沉浸式视角、即时游戏预览、AI人工智能、音频、中间件集成等一系列全新特性。   虚幻引擎4现已开始提供授权。 现在提供网盘下载地址,毕竟到官方下载很麻烦,还要$,呵呵,10分很值得,代码风格很好,注释很爽!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS子枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值