虚幻学习笔记13—C++静态和动态加载

2023-12-13 07:07:46

一、前言

? ? ? ? 我们在蓝图中可以很方便的添加各种需要的组件,那么在C++代码中要如何实现呢。在代码中分静态和动态加载,而无论静态和动态,加载的内容有资源和资源类,资源类通常为带资源的蓝图类。

二、实现

? ? ? ? 在实现静态或动态加载时,都需要提前在构造函数里创建所需的类型,代码如下:

	MyScene = CreateDefaultSubobject<USceneComponent>(TEXT("MyScene"));
	MyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyStaticMesh"));
	MyParticle = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MyParticle"));
	MyBox = CreateDefaultSubobject<UBoxComponent>(TEXT("MyBox"));
	MyAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("MyAudio"));

然后设置其父子级

	//设置父子级
	RootComponent = MyScene;//将MyScene作为默认的根组件
	MyMesh->SetupAttachment(MyScene);
	MyParticle->SetupAttachment(MyScene);
	MyBox->SetupAttachment(MyScene);
	MyAudio->SetupAttachment(MyBox);
2.1、静态加载资源

? ? ? ? 静态加载必须也在构造函数里,代码如下:

	//静态加载资源
	static ConstructorHelpers::FObjectFinder<UStaticMesh>TempStaticMesh(TEXT("/Script/Engine.StaticMesh'/Game/StarterContent/Shapes/Shape_Pipe.Shape_Pipe'"));
	MyMesh->SetStaticMesh(TempStaticMesh.Object);
	static ConstructorHelpers::FObjectFinder<UParticleSystem>TempParticle(TEXT("/Script/Engine.ParticleSystem'/Game/StarterContent/Particles/P_Fire.P_Fire'"));
	MyParticle->SetTemplate(TempParticle.Object);
	static ConstructorHelpers::FObjectFinder<USoundWave>TempSoundWave(TEXT("/Script/Engine.SoundWave'/Game/StarterContent/Audio/Collapse01.Collapse01'"));
	MyAudio->SetSound(TempSoundWave.Object);

其中”TEXT"里面的路径获取方法如下:

首先,在编辑器的内容里找到资源,然后鼠标右键点击“复制引用”,如图2.1.1所示,然后将复制的引用添加到上述的TEXT里面即可。

图2.1.1
2.2、静态加载类

? ? ? ? 静态加载的类也要在构造函数里,代码如下,注意:类和资源不同地方在于,类后面必须加上“_C”,否则会出现编译报错或运行崩溃的不可控情况。

	//静态加载类,复制引用后,文件名后面必须加上"_C",不然会运行崩溃
	static ConstructorHelpers::FClassFinder<AActor>TempMyActor(TEXT("/Script/Engine.Blueprint'/Game/StarterContent/Blueprints/Blueprint_WallSconce.Blueprint_WallSconce_C'"));
	MyActor = TempMyActor.Class;

? ? ? ? 另外,这里创建的加载的类并不能马上就显示在场景中,还只是在内存中,如果在变量定义的时候添加了“UPROPERTY(VisibleAnywhere, BlueprintReadOnly)“也只会显示在编辑界面中,如果要显示在场景中还需要实例化一下,但是实例化不能在构造函数中,代码如下:

	if (MyActor)
	{
		UE_LOG(LogTemp, Warning, TEXT("My Actor is:%s"), *MyActor->GetName());
		AActor* TempSpawnActor = GetWorld()->SpawnActor<AActor>(MyActor, FVector(100, 500, 100), FRotator::ZeroRotator);
	}
2.3、动态加载资源

? ? ? ? 动态加载通常用Load方法,这个和Unity的方法很相似。通常不会放在构造函数里,这点也和静态加载不同,具体代码如下,这里加载的资源会显示到场景中,如代码会替换之前静态加载的资源。

	//动态加载资源
	UStaticMesh* TempStaticMesh = LoadObject<UStaticMesh>(nullptr, TEXT("/Script/Engine.StaticMesh'/Game/StarterContent/Shapes/Shape_NarrowCapsule.Shape_NarrowCapsule'"));
	if (TempStaticMesh)
	{
		MyMesh->SetStaticMesh(TempStaticMesh);
	}
2.4、动态加载类

动态加载的类和静态加载类一样,在复制引用名称后面也要加“_C”,代码如下:

	//动态加载类
	UClass* TempClass = LoadClass<AActor>(this, TEXT("/Script/Engine.Blueprint'/Game/StarterContent/Blueprints/Blueprint_CeilingLight.Blueprint_CeilingLight_C'"));
	if (TempClass)
	{
		AActor* SpawanActor = GetWorld()->SpawnActor<AActor>(TempClass, FVector::ZeroVector, FRotator::ZeroRotator);
		UE_LOG(LogTemp, Warning, TEXT("Class Name:"), *TempClass->GetName());
	}

这样加载的类也是会直接呈现在场景中。

三、总结

3.1、静态加载必须在构造函数里实现。

3.2、静态加载的类,复制引用后,文件名后面必须加上”_C“,不然会造成编译不通过或运行崩溃等各种问题。

3.3、静态加载的类都在内存中,不能被显性的呈现在视口、场景中,动态加载的类可以。

文章来源:https://blog.csdn.net/zhangxiao13627093203/article/details/134932221
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。