UE5-Hot-Update (Ressourcen auf Ladeebene über das Pak-Paket laden und zur Stream-Ebene hinzufügen)

Bitte lesen Sie zuerst meinen letzten Artikel) UE5 Hot Update (Kochen, packen, laden und treten Sie auf einige Gruben im Pak-Paket
**

Lassen Sie uns wie die alte Regel über die Gruben sprechen, auf die wir zuerst getreten sind. **

Das Laden von Ebenen unterscheidet sich ein wenig vom Laden anderer Blueprint-Assets. Um andere Blueprint-Ressourcen zu laden, müssen wir eine neue FPakPlatformFile erstellen und initialisieren. Aber dieses FPakPlatformFile-Objekt kann das Level nicht laden, der Grund ist noch nicht bekannt. brauchen

FPakPlatformFile* PakPlatformFile_ = (FPakPlatformFile*)(FPlatformFileManager::Get().FindPlatformFile(FPakPlatformFile::GetTypeName()));

Nur dieses FPakPlatformFile-Objekt kann Level laden.

Geben Sie nun den Text ein, laden Sie die Level-Ressourcen über das Pak-Paket und öffnen Sie die Karte über das Streaming-Level. Es gibt drei Schritte:

1. Mounten Sie die .umap-Datei im Pak-Paket

//由于一个pak包里可能有多个关卡,所以关卡名为数组变量
void APakManager::LoadPak(TArray<FString>& LevelNames,const FName& InPakFullPath)
{
    
    
	LevelNames.Empty();
	FString fullPath = InPakFullPath.ToString();
	//初始化加载Pak包平台类
	OldPlatform = &FPlatformFileManager::Get().GetPlatformFile();
	UE_LOG(LogTemp, Warning, TEXT("LoadPakDelegate(): OnMountPak.IsBound() %s"), *fullPath);
	FPakPlatformFile* PakPlatformFile_ = (FPakPlatformFile*)(FPlatformFileManager::Get().FindPlatformFile(FPakPlatformFile::GetTypeName()));


	FString PakFileFullPath = InPakFullPath.ToString();
	//FString PakFileFullPath = InPakFullPath;
	if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*PakFileFullPath))
		return;
	//FString PakName = GetPakFileName(PakFileFullPath);

	TRefCountPtr<FPakFile> TmpPak = new FPakFile(OldPlatform, *PakFileFullPath, false);
	FString OldPakMountPoint = TmpPak->GetMountPoint();

	int32 ContentPos = OldPakMountPoint.Find("Content/");
	FString NewMountPath = OldPakMountPoint.RightChop(ContentPos);

	FString ProjectPath = FPaths::ProjectDir();
//判断是否是在编辑器
	if (GetWorld()->WorldType == EWorldType::PIE)
		ProjectPath = "../../../RobotEngine/";

	NewMountPath = ProjectPath + NewMountPath;
	TmpPak->SetMountPoint(*NewMountPath);

	if (PakPlatformFile_->Mount(*PakFileFullPath, 1, *NewMountPath))
	{
    
    
		TArray<FString> FoundFilenames;
		OldPakMountPoint = TmpPak->GetMountPoint();
		TmpPak->FindPrunedFilesAtPath(FoundFilenames, *TmpPak->GetMountPoint(), true, false, true);
		if (FoundFilenames.Num() > 0)
		{
    
    
			//if (GetWorld()->WorldType == EWorldType::Game)
			{
    
    
				for (int i = 0; i < FoundFilenames.Num(); ++i)
				{
    
    
					FString Filename(FoundFilenames[i]);
					if (Filename.EndsWith(TEXT(".uasset")))
					{
    
    

					}
					else if (Filename.EndsWith(TEXT(".umap")))
					{
    
    
						//通过一系列的String操作,从加载的关卡虚拟路径获取到关卡名
						GEngine->AddOnScreenDebugMessage(-1, 20.0f, FColor::Red, *Filename);
						FString PathDir = FPaths::ProjectContentDir();
						Filename.ReplaceInline(*PathDir, TEXT("/Game/"));
						FString leftName;
						FString NewFileName2;
						Filename.Split(TEXT("/"), &leftName, &NewFileName2, ESearchCase::Type::CaseSensitive, ESearchDir::FromEnd);

						NewFileName2.RemoveFromEnd(TEXT(".umap"));

						GEngine->AddOnScreenDebugMessage(-1, 20.0f, FColor::Red, *NewFileName2);
						//调用函数,将关卡名添加到流关卡中
						AddMapToWorld(NewFileName2);
						LevelNames.AddUnique(NewFileName2);
					}
				}
			}
		}
	}
	//设置回原来的读取方式,不然包内的资源可能访问不了
	FPlatformFileManager::Get().SetPlatformFile(*OldPlatform);
}

2. Fügen Sie die bereitgestellte .umap-Datei dem Level-Stream hinzu

void APakManager::AddMapToWorld(const FString& LevelName)
{
    
    
	FString LongPackageName;
	bool bOutSuccess = FPackageName::SearchForPackageOnDisk(LevelName, &LongPackageName);
	if (!bOutSuccess)
	{
    
    
		return;
	}
	UWorld* world = GetWorld();
	FString name = CreateStreamInstance(world, LongPackageName);
}

FString APakManager::CreateStreamInstance(UWorld* World, const FString& LongPackageName)
{
    
    
	const FString ShortPackageName = FPackageName::GetShortName(LongPackageName);
	const FString PackagePath = FPackageName::GetLongPackagePath(LongPackageName);

	FString UniqueLevelPackageName = PackagePath + TEXT("/") + World->StreamingLevelsPrefix + ShortPackageName;
	// Setup streaming level object that will load specified map
	UClass* StreamingClass = ULevelStreamingDynamic::StaticClass();
	ULevelStreamingDynamic* StreamingLevel = NewObject<ULevelStreamingDynamic>(World, StreamingClass, NAME_None, RF_Transient, NULL);

	StreamingLevel->SetWorldAssetByPackageName(FName(*UniqueLevelPackageName));
	StreamingLevel->LevelColor = FColor::MakeRandomColor();

	StreamingLevel->LevelTransform = FTransform(FRotator::ZeroRotator, FVector::ZeroVector);
	// Map to Load
	StreamingLevel->PackageNameToLoad = FName(*LongPackageName);
	StreamingLevel->SetShouldBeLoaded(false);
	StreamingLevel->SetShouldBeVisible(false);
	StreamingLevel->bShouldBlockOnLoad = false;


	World->AddUniqueStreamingLevel(StreamingLevel);
	//World->UpdateStreamingLevelShouldBeConsidered(StreamingLevel);

	return UniqueLevelPackageName;
}

3. Laden und schreiben Sie das Level in den Levelstream

void APakManager::LoadMap(const FString& LevelName, FLatentActionInfo LatentInfo)
{
    
    
	FString LongPackageName;
	bool bOutSuccess = FPackageName::SearchForPackageOnDisk(LevelName, &LongPackageName);
	if (!bOutSuccess)
	{
    
    
		return;
	}
	UWorld* world = GetWorld();
	UGameplayStatics::LoadStreamLevel(world, FName(*LevelName), true, false, LatentInfo);
}

void APakManager::UnLoadMap(const FString& LevelName, FLatentActionInfo LatentInfo)
{
    
    
	FString LongPackageName;
	bool bOutSuccess = FPackageName::SearchForPackageOnDisk(LevelName, &LongPackageName);
	if (!bOutSuccess)
	{
    
    
		return;
	}
	UWorld* world = GetWorld();
	UGameplayStatics::UnloadStreamLevel(world, FName(*LevelName), LatentInfo, false);
}

Seitdem kann das Level im Pak-Paket durch Aufruf von LoadPak zum Flow-Level hinzugefügt,
Bildbeschreibung hier einfügen
durch Aufruf von LoadMap geladen und
Bildbeschreibung hier einfügen
durch Aufruf von UnLoadMap in das Level geschrieben werden.
Bildbeschreibung hier einfügen

Supongo que te gusta

Origin blog.csdn.net/xialuhui/article/details/127447213
Recomendado
Clasificación