UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ExternalPackageHelper.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if WITH_EDITOR
6
9#include "UObject/Package.h"
13#include "Misc/ArchiveMD5.h"
14#include "Misc/PackageName.h"
15#include "Misc/PackagePath.h"
21#include "Engine/Level.h"
23
25{
26public:
28 {
29 public:
33
36 private:
37 const UObject* OldObject = nullptr;
38 const UPackage* SourcePackage = nullptr;
39 };
42
50 static ENGINE_API UPackage* CreateExternalPackage(const UObject* InObjectOuter, const FString& InObjectPath, EPackageFlags InFlags = FExternalPackageHelper::GetDefaultExternalPackageFlags(), const UExternalDataLayerAsset* InExternalDataLayerAsset = nullptr);
51
54
63 static ENGINE_API void SetPackagingMode(UObject* InObject, const UObject* InObjectOuter, bool bInIsPackageExternal, bool bInShouldDirty = true, EPackageFlags InExternalPackageFlags = FExternalPackageHelper::GetDefaultExternalPackageFlags());
64
71 static ENGINE_API FString GetExternalObjectsPath(const FString& InOuterPackageName, const FString& InPackageShortName = FString());
72
79 static ENGINE_API FString GetExternalObjectsPath(UPackage* InPackage, const FString& InPackageShortName = FString(), bool bTryUsingPackageLoadedPath = false);
80
81
88 static ENGINE_API FString GetExternalPackageName(const FString& InOuterPackageName, const FString& InObjectPath);
89
93 template<typename T>
94 static void LoadObjectsFromExternalPackages(UObject* InOuter, TFunctionRef<void(T*)> Operation);
95
97 {
98 // No flags
99 None = 0,
100
101 // Whether to check the object's package dirty flag. Controls whether only dirty or all external objects are returned.
102 CheckDirty = (1 << 0)
103 };
104
106
113 static ENGINE_API void GetExternalSaveableObjects(UObject* InOuter, TArray<UObject*>& OutObjects, EGetExternalSaveableObjectsFlags InFlags = EGetExternalSaveableObjectsFlags::CheckDirty);
114
120
121 /*
122 * Copies the file path of objects external package to the clipboard
123 */
125
130
135private:
137 static ENGINE_API FString GetExternalObjectPackageInstanceName(const FString& OuterPackageName, const FString& ObjectPackageName);
138};
139
140template<typename T>
141void FExternalPackageHelper::LoadObjectsFromExternalPackages(UObject* InOuter, TFunctionRef<void(T*)> Operation)
142{
143 TRACE_CPUPROFILER_EVENT_SCOPE(FExternalPackageHelper::LoadObjectsFromExternalPackages);
144
145 check(InOuter);
147 const FString OutermostPackageName = !OutermostPackage->GetLoadedPath().IsEmpty() ? OutermostPackage->GetLoadedPath().GetPackageName() : OutermostPackage->GetName();
149 const UExternalDataLayerAsset* ExternalDataLayerAsset = DataLayerInstanceProvider ? DataLayerInstanceProvider->GetRootExternalDataLayerAsset() : nullptr;
150 const FString RootPath = ExternalDataLayerAsset ? FExternalDataLayerHelper::GetExternalDataLayerLevelRootPath(ExternalDataLayerAsset, OutermostPackageName) : OutermostPackageName;
151 const FString ExternalObjectsPath = FExternalPackageHelper::GetExternalObjectsPath(RootPath);
153
154 // Do a synchronous scan of the world external objects path.
155 IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")).Get();
156 AssetRegistry.ScanSynchronous({ ExternalObjectsPath }, TArray<FString>());
157
158 // Find any redirects for this class and any of its derived classes so we can load older external objects (asset registry class does not redirect)
160 ClassPaths.Add(T::StaticClass()->GetClassPathName());
161
162 if(T::StaticClass() != UObject::StaticClass())
163 {
165 DerivedClasses.Add(T::StaticClass());
166 GetDerivedClasses(T::StaticClass(), DerivedClasses);
167
169 {
172
174 {
176 }
177 }
178 }
179
181 Filter.bRecursivePaths = true;
182 Filter.bIncludeOnlyOnDiskAssets = true;
183 Filter.ClassPaths = MoveTemp(ClassPaths);
184 Filter.bRecursiveClasses = true;
185 Filter.PackagePaths.Add(*ExternalObjectsPath);
188
189 ObjectPackageNames.Reserve(Assets.Num());
190 for (const FAssetData& Asset : Assets)
191 {
192 ObjectPackageNames.Add(Asset.PackageName.ToString());
193 }
194
195 FLinkerInstancingContext InstancingContext;
197
199 FName PackageResourceName = OuterPackage->GetLoadedPath().GetPackageFName();
200 const bool bInstanced = !PackageResourceName.IsNone() && (PackageResourceName != OuterPackage->GetFName());
201 if (bInstanced)
202 {
205 {
206 OuterInstancingContext = &OuterLinker->GetInstancingContext();
207 }
208
209 // Add packages of all outers to instancing context
212 while (ItObj)
213 {
214 const UPackage* Package = ItObj->GetPackage();
215 bool bIsAlreadyInSet = false;
217 if (!bIsAlreadyInSet)
218 {
219 InstancingContext.AddPackageMapping(Package->GetLoadedPath().GetPackageFName(), Package->GetFName());
220 }
221 ItObj = ItObj->GetOuter();
222 }
223
224 for (const FString& ObjectPackageName : ObjectPackageNames)
225 {
227
228 FName ObjectPackageFName = *ObjectPackageName;
230 {
232 }
233
234 // Remap to the a instanced package if it wasn't remapped already by the outer instancing context
236 {
237 InstancedName = *GetExternalObjectPackageInstanceName(OuterPackage->GetName(), ObjectPackageName);
238 }
239
241
242 // Create instance package
244 // Propagate RF_Transient
245 if (OuterPackage->HasAnyFlags(RF_Transient))
246 {
247 InstancePackage->SetFlags(RF_Transient);
248 }
250 }
251 }
252
253 const ELoadFlags LoadFlags = InOuter->GetPackage()->HasAnyPackageFlags(PKG_PlayInEditor) ? LOAD_PackageForPIE : LOAD_None;
254 for (int32 i = 0; i < ObjectPackageNames.Num(); i++)
255 {
256 if (UPackage* Package = LoadPackage(bInstanced ? InstancePackages[i] : nullptr, *ObjectPackageNames[i], LoadFlags, nullptr, &InstancingContext))
257 {
258 T* LoadedObject = nullptr;
260 {
261 if (T* TypedObj = Cast<T>(Object))
262 {
263 LoadedObject = TypedObj;
264 return false;
265 }
266 return true;
268
269 if (ensure(LoadedObject))
270 {
271 Operation(LoadedObject);
272 }
273 }
274 }
275}
276
277#endif
#define check(expr)
Definition AssertionMacros.h:314
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
#define DECLARE_EVENT_TwoParams(OwningType, EventName, Param1Type, Param2Type)
Definition DelegateCombinations.h:60
#define FRIEND_ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:17
uint32 ERenameFlags
Definition ObjectMacros.h:2302
EPackageFlags
Definition ObjectMacros.h:129
@ PKG_PlayInEditor
Set if the package was created for the purpose of PIE.
Definition ObjectMacros.h:150
@ Unreachable
Object is not reachable on the object graph.
@ RF_NoFlags
No flags, used to avoid a cast.
Definition ObjectMacros.h:555
@ RF_Transient
Don't save object.
Definition ObjectMacros.h:565
ELoadFlags
Definition ObjectMacros.h:68
@ LOAD_None
No flags.
Definition ObjectMacros.h:69
@ LOAD_PackageForPIE
This package is being loaded for PIE, it must be flagged as such immediately.
Definition ObjectMacros.h:88
UPackage * CreatePackage(const TCHAR *PackageName)
Definition UObjectGlobals.cpp:1002
void GetDerivedClasses(const UClass *ClassToLookFor, TArray< UClass * > &Results, bool bRecursive)
Definition UObjectHash.cpp:1883
void ForEachObjectWithPackage(const class UPackage *Package, TFunctionRef< bool(UObject *)> Operation, bool bIncludeNestedObjects, EObjectFlags ExclusionFlags, EInternalObjectFlags ExclusionInternalFlags)
Definition UObjectHash.cpp:1719
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition AssetRegistry.Build.cs:6
static ENGINE_API FString GetExternalDataLayerLevelRootPath(const UExternalDataLayerAsset *InExternalDataLayerAsset, const FString &InLevelPackagePath)
Definition ExternalDataLayerHelper.cpp:63
Definition LinkerInstancingContext.h:99
COREUOBJECT_API void AddPackageMapping(FName Original, FName Instanced)
Definition LinkerInstancingContext.cpp:259
Definition LinkerLoad.h:124
virtual FLinker * GetLinker() override
Definition LinkerLoad.h:629
Definition NameTypes.h:617
FORCEINLINE bool IsNone() const
Definition NameTypes.h:827
COREUOBJECT_API bool IsEmpty() const
Definition PackagePath.cpp:1136
Definition IAssetRegistry.h:263
Definition DataLayerInstanceProviderInterface.h:19
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
Definition AssetRegistryState.h:50
Definition Class.h:3793
Definition ExternalDataLayerAsset.h:16
bool IsA(OtherClassType SomeBase) const
Definition UObjectBaseUtility.h:619
COREUOBJECT_API UPackage * GetPackage() const
Definition UObjectBaseUtility.cpp:199
Definition Object.h:95
Definition Package.h:216
COREUOBJECT_API const FPackagePath & GetLoadedPath() const
Definition Package.cpp:312
UPackage * GetPackage(const UObject *Obj)
Definition ObjectFwd.cpp:33
Definition ARFilter.h:23
bool bRecursivePaths
Definition ARFilter.h:80
Definition AssetData.h:162
Definition CoreRedirects.h:88
static COREUOBJECT_API bool FindPreviousNames(ECoreRedirectFlags Type, const FCoreRedirectObjectName &NewObjectName, TArray< FCoreRedirectObjectName > &PreviousNames)
Definition CoreRedirects.cpp:1880
Definition UObjectGlobals.h:147
Definition TopLevelAssetPath.h:38