UE4 C++ 类的4种引用类型,和异步加载资产

UE4 C++ 类的4种引用类型,和异步加载资产

4种引用类型

	对象引用:引用 World 的实例对象。

就是直接定义

UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//对象引用
	UWorld* LoadPackageSoftObjectPath4;


	类引用:引用从 World 继承而来的类。

TSubclassOf 是提供 UClass 类型安全性的模板类
允许在类型安全的情况下传递 TClassType 的模板

UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//类引用
	TSubclassOf<UWorld>LoadPackageSoftObjectPath3;


软类引用:从类型的 World 继承的类的路径,该类型可能不会被加载。可用于异步加载类。

TSoftClassPtr是 FSoftObjectPtr 的模板化包装器,其工作方式类似于TSubclassOf,它可以在 UProperties 中用于蓝图子类

UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//软类引用
	TSoftClassPtr<UWorld> LoadPackageSoftObjectPath2;


	软对象引用: 类型为 World 的实例Object的路径,该类型可能不会被加载。可用于异步加载资产。

TSoftObjectPtr是通用FSoftObjectPtr的模板化包装器,可以在 UProperties 中使用

UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//软对象引用
	TSoftObjectPtr<UWorld> LoadPackageSoftObjectPath;

异步加载资产,这里异步加载关卡,打开关卡

C++类的游戏模式基础:

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "LoadLevelGameModeBase.generated.h"

/**
 * 
 */
UCLASS()
class LOADLEVEL_API ALoadLevelGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
public:
	bool bIsLoaded;

	UPROPERTY()
	FString LoadPackagePath;

	UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//软对象引用
	TSoftObjectPtr<UWorld> LoadPackageSoftObjectPath;

	UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//软类引用
	TSoftClassPtr<UWorld> LoadPackageSoftObjectPath2;
	
	UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//类引用
	TSubclassOf<UWorld>LoadPackageSoftObjectPath3;

	UPROPERTY(EditAnywhere,BlueprintReadOnly,Category="My")//对象引用
	UWorld* LoadPackageSoftObjectPath4;
	
	// 用于加载完成的回调
	DECLARE_DYNAMIC_DELEGATE(FOnAsyncLoadFinished);
public:
	UFUNCTION(BlueprintCallable,Category="My")
	void MyAsyncLoad(const FOnAsyncLoadFinished& OnAsyncLoadFinished);
	
	UFUNCTION(BlueprintCallable,Category="My")
	float GetLoadProgress();

};

// Copyright Epic Games, Inc. All Rights Reserved.


#include "LoadLevelGameModeBase.h"

//开始异步加载

void ALoadLevelGameModeBase::MyAsyncLoad(const FOnAsyncLoadFinished& OnAsyncLoadFinished)
{
	//不使用GetBaseFilename,编译 error C4458: LoadPackageAsync failed to begin to load a package···
	LoadPackagePath = FPaths::GetBaseFilename(LoadPackageSoftObjectPath.ToString(), false);
	bIsLoaded = false;
	UE_LOG(LogTemp, Warning, TEXT("String: %s"), *LoadPackagePath);
	
	LoadPackageAsync(
		LoadPackagePath,
		FLoadPackageAsyncDelegate::CreateLambda([=](const FName& PackageName, UPackage* LoadedPackage, EAsyncLoadingResult::Type Result)
			{
			 //开始
				if (Result == EAsyncLoadingResult::Failed)
				{
					UE_LOG(LogTemp, Warning, TEXT("Load Failed"));
				}
				else if (Result == EAsyncLoadingResult::Succeeded)//加载完毕
					{
						bIsLoaded = true;
						UE_LOG(LogTemp, Warning, TEXT("Load Succeeded"));
						OnAsyncLoadFinished.ExecuteIfBound();//调用绑定的事件,
					}
			}
		), 0, PKG_ContainsMap);
}

//获取加载的进度 -1 —— 100
float ALoadLevelGameModeBase::GetLoadProgress()
{
		float FloatPercentage = GetAsyncLoadPercentage(*LoadPackagePath);
		if (!bIsLoaded)
		{
			FString ResultStr = FString::Printf(TEXT("Percentage: %f"), FloatPercentage);
			GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Green, ResultStr);
			UE_LOG(LogTemp, Warning, TEXT("Percentage: %f"), FloatPercentage);
		}
		else
		{
			FloatPercentage = 100;
		}
		return FloatPercentage;
}

这个是开始加载和加载完成

namespace EAsyncLoadingResult
{
	enum Type
	{
		/** Package failed to load */
		Failed,
		/** Package loaded successfully */
		Succeeded,
		/** Async loading was canceled */
		Canceled
	};
}

主要看LoadPackageAsync这个函数的使用:

在这里插入图片描述
了解后用生成一个继承游戏模式基础的蓝图类
在蓝图类里调用和赋初值

在这里插入图片描述
加载完后打开关卡就行了

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,你需要创建一个继承自`USaveGame`的保存游戏数据的,并在其中定义需要保存的数据成员。接下来,你需要在异步加载关卡时加载这些数据。 以下是一个简单的示例: ```c++ // MySaveGame.h #pragma once #include "CoreMinimal.h" #include "GameFramework/SaveGame.h" #include "MySaveGame.generated.h" UCLASS() class UMySaveGame : public USaveGame { GENERATED_BODY() public: UPROPERTY(BlueprintReadWrite) FString LevelName; }; // MyLevelLoader.h #pragma once #include "CoreMinimal.h" #include "Engine/LevelStreamingDynamic.h" #include "MySaveGame.h" #include "MyLevelLoader.generated.h" UCLASS() class AMyLevelLoader : public AActor { GENERATED_BODY() public: AMyLevelLoader(); UFUNCTION(BlueprintCallable) void LoadLevelAsync(const FString& LevelName); void LoadLevelAsync_Internal(const FString& LevelName); UFUNCTION() void OnLevelLoaded(); private: UPROPERTY() ULevelStreamingDynamic* StreamingLevel; UPROPERTY() UMySaveGame* SaveGame; }; // MyLevelLoader.cpp #include "MyLevelLoader.h" #include "Kismet/GameplayStatics.h" #include "Engine/World.h" AMyLevelLoader::AMyLevelLoader() { PrimaryActorTick.bCanEverTick = false; StreamingLevel = NewObject<ULevelStreamingDynamic>(this, ULevelStreamingDynamic::StaticClass()); StreamingLevel->bShouldBeLoaded = false; StreamingLevel->bShouldBeVisible = false; } void AMyLevelLoader::LoadLevelAsync(const FString& LevelName) { SaveGame = Cast<UMySaveGame>(UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass())); if (SaveGame != nullptr) { SaveGame->LevelName = LevelName; SaveGame->SaveAsync(0); } FStreamableManager& Streamable = UAssetManager::GetStreamableManager(); Streamable.RequestLevel(StreamingLevel->GetWorldAssetPackageFName(LevelName), FStreamableDelegate::CreateUObject(this, &AMyLevelLoader::LoadLevelAsync_Internal, LevelName)); } void AMyLevelLoader::LoadLevelAsync_Internal(const FString& LevelName) { StreamingLevel->SetWorldAssetByPackageName(LevelName); StreamingLevel->bShouldBeLoaded = true; UWorld* World = GetWorld(); if (World != nullptr) { StreamingLevel->LevelColor = FColor::MakeRandomColor(); StreamingLevel->LevelTransform = FTransform(FRotator::ZeroRotator, FVector(0.f, 0.f, 0.f), FVector(1.f, 1.f, 1.f)); World->AddLevelStreamingActor(StreamingLevel, GetActorTransform()); } } void AMyLevelLoader::OnLevelLoaded() { if (SaveGame != nullptr) { FString LevelName = SaveGame->LevelName; SaveGame->Delete(); SaveGame = nullptr; // Do something with the loaded level... } } ``` 在上面的示例中,`UMySaveGame`保存了需要在异步加载关卡时加载的数据成员。`AMyLevelLoader`是一个继承自`AActor`的,它有一个`LoadLevelAsync`函数,它会异步加载指定名称的关卡,并在加载完成后调用`OnLevelLoaded`函数。在`LoadLevelAsync_Internal`函数中,我们使用`ULevelStreamingDynamic`加载关卡,并在加载完成后将其添加到世界中。在`OnLevelLoaded`函数中,我们可以获取保存在`UMySaveGame`对象中的数据成员,并进行后续操作。 请注意,以上示例仅用于演示目的,实际使用时可能需要进行更多的错误处理和数据验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Li~蒙一

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

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

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

打赏作者

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

抵扣说明:

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

余额充值