ue5 wp生成cell
2023-06-15 19:28 kk20161206 阅读(82) 评论(0) 编辑 收藏 举报ue5 wp生成cell
bool UWorldPartition::GenerateStreaming(TArray<FString>* OutPackagesToGenerate) { return GenerateContainerStreaming(ActorDescContainer, OutPackagesToGenerate); } bool UWorldPartition::GenerateContainerStreaming(const UActorDescContainer* InActorDescContainer, TArray<FString>* OutPackagesToGenerate /* = nullptr */) { FActorDescList* ModifiedActorsDescList = nullptr; FStreamingGenerationLogErrorHandler LogErrorHandler; FStreamingGenerationMapCheckErrorHandler MapCheckErrorHandler; IStreamingGenerationErrorHandler* ErrorHandler = &LogErrorHandler; if (bIsPIE) { ModifiedActorsDescList = &RuntimeHash->ModifiedActorDescListForPIE; // In PIE, we always want to populate the map check dialog ErrorHandler = &MapCheckErrorHandler; } // Dump state log const TCHAR* StateLogSuffix = bIsPIE ? TEXT("PIE") : (IsRunningGame() ? TEXT("Game") : (IsRunningCookCommandlet() ? TEXT("Cook") : TEXT("Manual"))); TUniquePtr<FArchive> LogFileAr = FWorldPartitionStreamingGenerator::CreateDumpStateLogArchive(StateLogSuffix); FHierarchicalLogArchive HierarchicalLogAr(*LogFileAr); FWorldPartitionStreamingGenerator StreamingGenerator(ModifiedActorsDescList, ErrorHandler, IsStreamingEnabled()); // Preparation Phase StreamingGenerator.PreparationPhase(InActorDescContainer); StreamingGenerator.DumpStateLog(HierarchicalLogAr); // Generate streaming check(!StreamingPolicy); StreamingPolicy = NewObject<UWorldPartitionStreamingPolicy>(const_cast<UWorldPartition*>(this), WorldPartitionStreamingPolicyClass.Get(), NAME_None, bIsPIE ? RF_Transient : RF_NoFlags); check(RuntimeHash); if (RuntimeHash->GenerateStreaming(StreamingPolicy, StreamingGenerator.GetStreamingGenerationContext(), OutPackagesToGenerate)) { //if (IsRunningCookCommandlet()) { RuntimeHash->DumpStateLog(HierarchicalLogAr); } StreamingPolicy->PrepareActorToCellRemapping(); return true; } return false; }
调用generateStream的函数:
TArray<ICookPackageSplitter::FGeneratedPackage> FWorldPartitionCookPackageSplitter::GetGenerateList(const UPackage* OwnerPackage, const UObject* OwnerObject) { // TODO: Make WorldPartition functions const so we can honor the constness of the OwnerObject in this API function const UWorld* ConstPartitionedWorld = ValidateDataObject(OwnerObject); UWorld* PartitionedWorld = const_cast<UWorld*>(ConstPartitionedWorld); // Store the World pointer to declare it to GarbageCollection; we do not want to allow the World to be Garbage Collected // until we have finished all of our PreSaveGeneratedPackage calls, because we store information on the World // that is necessary for populate ReferencedWorld = PartitionedWorld; check(!bInitializedPhysicsSceneForSave && !bForceInitializedWorld); bInitializedPhysicsSceneForSave = GEditor->InitializePhysicsSceneForSaveIfNecessary(PartitionedWorld, bForceInitializedWorld); // Manually initialize WorldPartition UWorldPartition* WorldPartition = PartitionedWorld->PersistentLevel->GetWorldPartition(); // We expect the WorldPartition has not yet been initialized ensure(!WorldPartition->IsInitialized()); WorldPartition->Initialize(PartitionedWorld, FTransform::Identity); bInitializedWorldPartition = true; TArray<FString> WorldPartitionGeneratedPackages; WorldPartition->GenerateStreaming(&WorldPartitionGeneratedPackages); TArray<ICookPackageSplitter::FGeneratedPackage> PackagesToGenerate; PackagesToGenerate.Reserve(WorldPartitionGeneratedPackages.Num()); for (const FString& PackageName : WorldPartitionGeneratedPackages) { ICookPackageSplitter::FGeneratedPackage& GeneratedPackage = PackagesToGenerate.Emplace_GetRef(); GeneratedPackage.RelativePath = PackageName; GeneratedPackage.GeneratedRootPath = OwnerPackage->GetName(); // all packages we generate get a ULevel from CreateEmptyLevelForRuntimeCell and are hence maps GeneratedPackage.SetCreateAsMap(true); // @todo_ow: Set dependencies once we get iterative cooking working } return PackagesToGenerate; }
和UWorldPartition的beginPlay函数。editor下的函数。
前者被调用
bool FGeneratorPackage::TryGenerateList(UObject* OwnerObject, FPackageDatas& PackageDatas)里。
被调用:
UE::Cook::EPollStatus UCookOnTheFlyServer::QueueGeneratedPackages(UE::Cook::FGeneratorPackage& Generator, UE::Cook::FPackageData& PackageData) { using namespace UE::Cook; ICookPackageSplitter* Splitter = Generator.GetCookPackageSplitterInstance(); UObject* SplitObject = Generator.FindSplitDataObject(); FCookGenerationInfo& Info = Generator.GetOwnerInfo(); if (!SplitObject) { UE_LOG(LogCook, Error, TEXT("Could not find SplitDataObject %s"), *Generator.GetSplitDataObjectName().ToString()); return EPollStatus::Error; } if (Info.GetSaveState() <= FCookGenerationInfo::ESaveState::GenerateList) { // Call the splitter to generate the list if (!Generator.TryGenerateList(SplitObject, *PackageDatas)) { return EPollStatus::Error; }
被调用:
UE::Cook::EPollStatus UCookOnTheFlyServer::PrepareSaveInternal(UE::Cook::FPackageData& PackageData,
UE::Cook::FCookerTimer& Timer, bool bPrecaching)
{
UE::Cook::FCookerTimer& Timer, bool bPrecaching)
{
被调用
UE::Cook::EPollStatus UCookOnTheFlyServer::PrepareSave(UE::Cook::FPackageData& PackageData,
UE::Cook::FCookerTimer& Timer, bool bPrecaching)
UE::Cook::FCookerTimer& Timer, bool bPrecaching)
和
UE::Cook::EPollStatus UCookOnTheFlyServer::PrepareSaveInternal(UE::Cook::FPackageData& PackageData,
UE::Cook::FCookerTimer& Timer, bool bPrecaching)
UE::Cook::FCookerTimer& Timer, bool bPrecaching)
结构
/** * Helper that wraps a ICookPackageSplitter, gets/caches packages to generate and provide * the necessary to iterate over all of them iteratively. */ struct FGeneratorPackage { public: /** Store the provided CookPackageSplitter and prepare the packages to generate. */ FGeneratorPackage(UE::Cook::FPackageData& InOwner, const UObject* InSplitDataObject, ICookPackageSplitter* InCookPackageSplitterInstance); ~FGeneratorPackage(); /** Clear references to owned generated packages, and mark those packages as orphaned */ void ClearGeneratedPackages(); /** Call the Splitter's GetGenerateList and create the PackageDatas */ bool TryGenerateList(UObject* OwnerObject, FPackageDatas& PackageDatas); /** Accessor for the packages to generate */ TArrayView<UE::Cook::FCookGenerationInfo> GetPackagesToGenerate() { return PackagesToGenerate; } /** Return the GenerationInfo used to save the Generator's UPackage */ UE::Cook::FCookGenerationInfo& GetOwnerInfo() { return OwnerInfo; } /** Return owner FPackageData. */ UE::Cook::FPackageData& GetOwner() { return *OwnerInfo.PackageData; } /** Return the GenerationInfo for the given PackageData, or null if not found. */ UE::Cook::FCookGenerationInfo* FindInfo(const FPackageData& PackageData); const UE::Cook::FCookGenerationInfo* FindInfo(const FPackageData& PackageData) const; /** Return CookPackageSplitter. */ ICookPackageSplitter* GetCookPackageSplitterInstance() const { return CookPackageSplitterInstance.Get(); } /** Return the SplitDataObject's FullObjectPath. */ const FName GetSplitDataObjectName() const { return SplitDataObjectName; } /** * Find again the split object from its name, or return null if no longer in memory. * It may have been GC'd and reloaded since the last time we used it. */ UObject* FindSplitDataObject() const; void ResetSaveState(FCookGenerationInfo& Info, UPackage* Package, UE::Cook::EReleaseSaveReason ReleaseSaveReason); int32& GetNextPopulateIndex() { return NextPopulateIndex; } /** Callbacks during garbage collection */ void PreGarbageCollect(FCookGenerationInfo& Info, TArray<UObject*>& GCKeepObjects, TArray<UPackage*>& GCKeepPackages, TArray<FPackageData*>& GCKeepPackageDatas, bool& bOutShouldDemote); void PostGarbageCollect(); /** Call CreatePackage and set PackageData for deterministic generated packages, and update status. */ UPackage* CreateGeneratedUPackage(FCookGenerationInfo& GenerationInfo, const UPackage* OwnerPackage, const TCHAR* GeneratedPackageName); /** Mark that the generator or a generated package has saved, to keep track of when *this is no longer needed. */ void SetPackageSaved(FCookGenerationInfo& Info, FPackageData& PackageData); /** Return whether list has been generated and all generated packages have been populated */ bool IsComplete() const; void UpdateSaveAfterGarbageCollect(const FPackageData& PackageData, bool& bInOutDemote); UPackage* GetOwnerPackage() const { return OwnerPackage.Get(); }; void SetOwnerPackage(UPackage* InPackage) { OwnerPackage = InPackage; } private: void ConditionalNotifyCompletion(ICookPackageSplitter::ETeardown Status); /** PackageData for the package that is being split */ FCookGenerationInfo OwnerInfo; /** Name of the object that prompted the splitter creation */ FName SplitDataObjectName; /** Cached CookPackageSplitter */ TUniquePtr<ICookPackageSplitter> CookPackageSplitterInstance; /** Recorded list of packages to generate from the splitter, and data we need about them */ TArray<FCookGenerationInfo> PackagesToGenerate; TWeakObjectPtr<UPackage> OwnerPackage; int32 NextPopulateIndex = 0; int32 RemainingToPopulate = 0; bool bNotifiedCompletion = false; };