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());
}
}