UE4異步加載場景(1)

1
說UE4異步加載場景,首先大家都能想到的就是流關卡(Level Streaming),這也是一種比較常見的異步加載場景的方法,官方提供了比較詳細的使用方法大家可以看官方文檔。
我們這裏不說流關卡(Level Streaming)這種方式,我們用異步加載場景依賴資源的方式來解決異步加載場景的問題。說到異步加載場景依賴資源包,其實官方提供瞭如何獲得藍圖依賴資源的函數接口。我自己只要稍微封裝一下做成小工具就可以了。
第一篇呢我們就主要介紹這個工具,我會把工具插件附在文章末尾供大家下載。代碼量很少有興趣的大家可以閱讀一下。
這個工具的功能就是把場景依賴的所有資源路徑存儲到一張DataTable中,這樣其實就相當於這個場景的依賴資源路徑都有了。後面我們進行異步加載場景時候直接加載DataTable的資源路徑即可。
後面一篇我會把我地異步加載場景代碼貼給大家。(UE版本4.23)圖片已經標註了按鈕功能,就是導出當前場景的所有依賴資源,並且還提供了一個根據場景表格,一次行導出多場景的依賴資源,大家配置一下場景表格,點一下表格導出就是根據場景表格導出
圖片已經標註了按鈕功能,就是導出當前場景的所有依賴資源,並且還提供了一個根據場景表格,一次行導出多場景的依賴資源,大家配置一下場景表格,點一下表格導出就是根據場景表格導出.
我發現資源審覈有點慢,因爲插件本身代碼很少我貼代碼出來給大家,下面這個代碼就是核心插件代碼。

// Fill out your copyright notice in the Description page of Project Settings.


#include "ExpoortJsonSceneEditor.h"
#include "AssetRegistryModule.h"
#include "DesktopPlatform/Public/IDesktopPlatform.h"
#include "SlateApplication.h"
#include "DesktopPlatform/Public/DesktopPlatformModule.h"
#include "FileHelper.h"
#include "FileHelpers.h"
#include "DataConfig.h"
#include "Editor.h"

void UExpoortJsonSceneEditor::RecursiveGetDependencies(const FName& PackageName, TArray<FName>& AllDependencies, bool isFirst)
{
	if (!PackageName.IsNone())
	{
		FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
		TArray<FName> Dependencies;
		AssetRegistryModule.Get().GetDependencies(PackageName, Dependencies);
		if (isFirst &&
			!AllDependencies.Contains(PackageName) &&
			AddToSourceMapCondition(PackageName.ToString()))
		{
			AllDependencies.Add(PackageName);
		}

		for (auto DependsIt = Dependencies.CreateConstIterator(); DependsIt; ++DependsIt)
		{
			if (!AllDependencies.Contains(*DependsIt))
			{
				if (AddToSourceMapCondition((*DependsIt).ToString()))
				{
					AllDependencies.Add(*DependsIt);
					RecursiveGetDependencies(*DependsIt, AllDependencies, false);
				}
			}
		}
	}
}

bool UExpoortJsonSceneEditor::AddToSourceMapCondition(FString pathStr)
{
	if (pathStr.Contains("/Game/Map") || 
		pathStr.Contains("/Game/Moive")|| 
		pathStr.Contains("/Game/Maps")|| 
		pathStr.StartsWith("/Engine") || 
		pathStr.StartsWith("/Script"))
	{
		return false;
	}
	return true;
}

void UExpoortJsonSceneEditor::ExportCurrentSceneSources(FString tablePath)
{
	if (tablePath == "")
	{
		tablePath = FString("DataTable'/RefreshPointEditor/DataTable/SceneDependDataTable.SceneDependDataTable'");
	}
	UWorld* getWorld = GEditor->GetEditorWorldContext().World();
	if (!getWorld)
	{
		UE_LOG(LogTemp,Warning,TEXT("GetEditorWorld is NUll"));
		return;
	}
	FString sceneName = getWorld->GetPathName(); 
	GetPackageNameFromPathName(sceneName);
	UDataTable* getData = LoadObject<UDataTable>(NULL, *tablePath);
	FSceneDependConfig newRowData;
	newRowData.SceneName = sceneName;
	if (getData)
	{
		FSceneDependConfig* getRowData = getData->FindRow<FSceneDependConfig>(FName(*sceneName),"");
		if (getRowData)
		{
			getData->RemoveRow(FName(*sceneName));
		}
	}
	RecursiveGetDependencies(FName(*sceneName),newRowData.SceneDependSources,true);
	newRowData.SceneDependSources.RemoveAt(0);
	getData->AddRow(FName(*sceneName), newRowData);
	SaveDataTable(getData);
	UE_LOG(LogTemp, Warning, TEXT("ExportCurrentSceneSources"));
}

void UExpoortJsonSceneEditor::ExportSceneTableSources(FString tableDataPath, FString tableScenePath)
{
	if (tableDataPath == "")
	{
		tableDataPath = FString("DataTable'/RefreshPointEditor/DataTable/SceneDependDataTable.SceneDependDataTable'");
	}
	if (tableScenePath == "")
	{
		tableScenePath = FString("DataTable'/RefreshPointEditor/DataTable/SceneDataTable.SceneDataTable'");
	}
	TArray<FSceneTableConfig*> allSceneRows;
	UDataTable* getTableData = LoadObject<UDataTable>(NULL, *tableDataPath);
	UDataTable* getSceneData = LoadObject<UDataTable>(NULL, *tableScenePath);
	if (getSceneData)
	{
		getSceneData->GetAllRows("", allSceneRows);
	}
	if (getTableData)
	{
		getTableData->EmptyTable();
	}

	for (auto it: allSceneRows)
	{
		FSceneTableConfig* newRowData = it;
		if (newRowData)
		{
			FString sceneName = newRowData->SceneName;
			FSceneDependConfig dependSource;
			dependSource.SceneName = sceneName;
			RecursiveGetDependencies(FName(*newRowData->SceneName), dependSource.SceneDependSources, true);
			getTableData->AddRow(FName(*sceneName), dependSource);
			
		}
	}

	SaveDataTable(getSceneData);
	UE_LOG(LogTemp, Warning, TEXT("ExportSceneTableSources"));
}

void UExpoortJsonSceneEditor::GetPackageNameFromPathName(FString& pathName)
{
	int32 Flag = pathName.Find(FString("."));
	if (Flag > 0)
	{
		pathName = pathName.Mid(0, Flag);
	}
}

void UExpoortJsonSceneEditor::SaveSceneJsonFile(FString jsonTxt, FString FileTypes, FString DefaultTypes)
{
	/*const FString FileTypes = TEXT("Refresh Point CSV (*.csv)|*.csv");
	SaveSceneJsonFile(JsonTxt, FileTypes, TEXT(".csv"));*/
	IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
	const void* ParentWindowWindowHandle = FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr);
	FString Title = ("ExportJSONTitle");
	const FString CurrentFilename = "RefreshPoint";
	TArray<FString> OutFilenames;
	DesktopPlatform->SaveFileDialog(
		ParentWindowWindowHandle,
		Title,
		(CurrentFilename.IsEmpty()) ? TEXT("") : FPaths::GetPath(CurrentFilename),
		(CurrentFilename.IsEmpty()) ? TEXT("") : FPaths::GetBaseFilename(CurrentFilename) + DefaultTypes,
		FileTypes,
		EFileDialogFlags::None,
		OutFilenames
	);
	if (OutFilenames.Num() > 0)
	{
		FFileHelper::SaveStringToFile(jsonTxt, *OutFilenames[0]);
	}
}

void UExpoortJsonSceneEditor::SaveDataTable(UDataTable* saveTble)
{
	if (saveTble->IsAsset())
	{
		TArray<UPackage*> PackagesToSave;
		PackagesToSave.Add(saveTble->GetOutermost());

		UEditorLoadingAndSavingUtils::SavePackages(PackagesToSave, false);
		UE_LOG(LogTemp, Warning, TEXT("Save %s SUCCESS!"), *saveTble->GetName());
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章